Prepare data for various DGE analyses

Get situated

Set working directory (wd)


Load necessary libraries


Set options

  • Use normal numbers instead of default scientific numbers in plots
  • Do not limit number of overlaps when including labels in plots
options(scipen=999)
options(ggrepel.max.overlaps = Inf)


Initialize necessary functions


Load in Excel spreadsheet of samples names and variables

The spreadsheet includes Alison’s original sample names; we can use this information to associate the new sample names, which are made up of DESeq2 GLM variables, with the old names, which reflect Alison’s wet-lab, library-prep, etc. work


Load in and process featureCounts tables

Process the sense featureCounts table


Process the antisense featureCounts table


Create tibble: Antisense S. cerevisiae counts, sense K. lactis counts

Record tibble t_fc’s positional information in a GRanges object

pos_info will be used in DESeq2 processing, post-processing, etc.



Perform normalization and run DGE analyses

Perform prep work

Establish table of variables for dds—i.e., a “master” model matrix

  • dds stands for “DESeq2 dataset” and is a DESeqDataSet object
  • variables for dds are
    • strain
    • state
    • time
    • kit (tcn for “Tecan”, ovn for “Ovation”)
    • transcription (N for “nascent”, SS for “steady state”)
    • auxin
    • timecourse
    • replicate
    • technical



Do prep work for running DESeq2

Make the counts matrix


Make the model matrix


Make the DESeqDataSet, dds

  • Use counts_data for the featureCount tallies
  • Use col_data for setting up the GLM
  • Use pos_info for adding feature metadata, subsequent subsetting, etc.
dds <- DESeq2::DESeqDataSetFromMatrix(
    countData = counts_data,
    colData = col_data,
    design = ~ strain,  # Vary on strain: n3-d vs o-d
    rowRanges = pos_info
)

#  Make a back-up of the DESeqDataSet object
bak.dds <- dds

#  How do things look?
# dds %>% BiocGenerics::counts() %>% head()
# dds@rowRanges
# dds@design
# dds@assays


Prefilter dds

#TODO Let’s keep this in mind and try it if we come to think lowly expressed genes are skewing results.

# threshold <- 1000
# dds_filt <- dds[rowSums(BiocGenerics::counts(dds)) >= threshold, ]
# 
#  Breakdown
#    0 13166
#    1 12822
#    2 12719
#    5 12540
#   10 12358
#   20 12144
#   50 11764
#  100 11403
#  200 10927
#  500 10015
# 1000 8822
# 
# rm(threshold, dds_filt)



I. Run PCA, etc.

Generate non-normalized counts

norm_non <- dds[dds@rowRanges$genome == "S_cerevisiae", ] %>%
    SummarizedExperiment::assay() %>%
    as.data.frame()
norm_non$feature_init <- dds@rowRanges$feature_init[
    dds@rowRanges$genome == "S_cerevisiae"
]

#  Associate non-normalized values with feature metadata
norm_non <- dplyr::full_join(
    norm_non,
    t_fc[(t_fc$genome == "S_cerevisiae"), 1:9],
    by = "feature_init"
) %>%
    dplyr::as_tibble()


Generate normalized counts

Calculate rlog-normalized (unblinded) counts

norm_r <- DESeq2::rlog(
    dds[dds@rowRanges$genome == "S_cerevisiae", ],
    blind = FALSE
) %>%
    SummarizedExperiment::assay() %>%
    as.data.frame()
norm_r$feature_init <- dds@rowRanges$feature_init[
    dds@rowRanges$genome == "S_cerevisiae"
]

#  Associate normalized values with feature metadata
norm_r <- dplyr::full_join(
    norm_r,
    t_fc[t_fc$genome == "S_cerevisiae", 1:9],
    by = "feature_init"
) %>%
    dplyr::as_tibble()


Calculate GeTMM-normalized counts

More details on this relatively new method of normalization, which combines inter- and intra-sample normalization methods and (appears to) perform quite well:

#  Isolate raw counts for samples of interest
raw <- dds %>%
    SummarizedExperiment::assay() %>%
    as.data.frame()
raw$feature_init <- dds@rowRanges$feature_init

#  Associate non-normalized values with feature metadata
raw <- dplyr::full_join(
    raw,
    t_fc[, c(seq(1,9))],
    by = "feature_init"
) %>%
    dplyr::as_tibble()

#  Calculate counts per kb of gene length (i.e., correct counts for gene
#+ length); gene length is initially in bp and converted to kb
rpk <- ((raw[, 1:5] * 10^3) / raw$length)
rpk[, 6:14] <- raw[, 6:14]

#  Calculate normalization factors using the raw spike-in (K. lactis) counts
norm_KL <- edgeR::calcNormFactors(
    raw[(rpk$genome == "K_lactis"), ][, 1:5]
)

#  Create factor for categories (groups)
model_variables <- stringr::str_split(colnames(rpk[, 1:5]), "_") %>%
    as.data.frame(
        row.names = c(
            "sample", "stage", "day", "kit", "tx", "aux", "tc", "rep", "tech"
        ),
        col.names = paste0("s", c(1:5))
    ) %>%
    t() %>%
    tibble::as_tibble()

group <- factor(
    # Second level is numerator, first level is denominator
    model_variables$sample,
    levels = c("o-d", "n3-d")
)

rm(model_variables)

#  Create edgeR DGEList object composed of S. cerevisiae counts per kb gene
#+ length
dgel <- edgeR::DGEList(
    counts = rpk[rpk$genome == "S_cerevisiae", ][, 1:5],
    group = group
)

#  In the DGEList object, include the normalization factors calculated from
#+ spike-in information
dgel$samples$norm.factors <- norm_KL

#  Check that the normalization factors for each library are appropriately
#+ assigned
dgel$samples

#  Scale the values to counts-per-million
norm_g <- edgeR::cpm(dgel) %>% tibble::as_tibble()
norm_g[, 6:14] <- rpk[rpk$genome == "S_cerevisiae", 6:14]
norm_g

#  Clean up unneeded variables
rm(raw, rpk, norm_KL, group)
rm(dgel)  #TODO Delete dgel? Or use it for trying out DE analyses with edgeR?


Calculate TPM-normalized counts

#  Isolate raw counts for samples of interest
raw <- dds %>%
    SummarizedExperiment::assay() %>%
    as.data.frame()
raw$feature_init <- dds@rowRanges$feature_init

#  Associate non-normalized values with feature metadata
raw <- dplyr::full_join(
    raw,
    t_fc[, 1:9],
    by = "feature_init"
) %>%
    dplyr::as_tibble()

#  Calculate counts per kb of gene length (i.e., correct counts for gene
#+ length or do an "RPK normalization"); then, divide RPK-normalized elements
#+ by the sum of sample RPK divided by one million: this does the actual TPM
#+ normalization
rpk <- tpm <- ((raw[, 1:5] * 10^3) / raw$length)
for (i in 1:ncol(rpk)) {
    tpm[, i] <- (rpk[, i] / sum(rpk[, i] / 1e6))
}

tpm[, 6:14] <- raw[, 6:14]
norm_t <- tpm[tpm$genome == "S_cerevisiae", ]

rm(raw, rpk, tpm)


Run PCA with variously normalized counts

Part 1

#  Make the following code generic --------------------------------------------
#+ ...so that we can try it with different normalization objects (counts
#+ normalized in different ways)
# norm <- norm_non
norm <- norm_r
# norm <- norm_g
# norm <- norm_t


#  Create a PCAtools "pca" S4 object for the normalized counts ----------------
#+ Assign unique row names too
obj_pca <- PCAtools::pca(
    norm[, c(1:5)],
    metadata = dds[dds@rowRanges$genome != "K_lactis", ]@colData
)
rownames(obj_pca$loadings) <- make.names(
    dds[dds@rowRanges$genome != "K_lactis", ]@rowRanges$feature,
    unique = TRUE
)


#  Determine "significant" PCs with Horn's parallel analysis ------------------
#+ See Horn, 1965
horn <- PCAtools::parallelPCA(mat = sapply(norm[, c(1:5)], as.double))
Warning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than availableWarning: more singular values/vectors requested than available
#  Determine "significant" principle components with the elbow method ---------
#+ See Buja and Eyuboglu, 1992
elbow <- PCAtools::findElbowPoint(obj_pca$variance)


#  Evaluate cumulative proportion of explained variance with a scree plot -----
scree <- draw_scree_plot(obj_pca, horn = horn$n, elbow = elbow)
scree

# save_title <- paste0("panel-plot", ".", "scree", ".pdf")
# ggplot2::ggsave(paste0(args$directory_out, "/", save_title), scree)
#TODO Work up some logic for outfile names, location(s) for outfiles, etc.


#  Save component loading vectors in their own data frame ---------------------
loadings <- as.data.frame(obj_pca$loadings)

#  Evaluate the component loading vectors for the number of significant PCs
#+ identified via the elbow method plus two
PCs <- paste0("PC", 1:(as.numeric(elbow) + 2))
top_loadings_all <- lapply(
    PCs, get_top_loadings, x = loadings, z = "all", a = TRUE
)
top_loadings_pos <- lapply(
    PCs, get_top_loadings, x = loadings, z = "pos", a = TRUE
)
top_loadings_neg <- lapply(
    PCs, get_top_loadings, x = loadings, z = "neg", a = TRUE
)

names(top_loadings_all) <-
    names(top_loadings_pos) <-
    names(top_loadings_neg) <-
    PCs
# rm(PCs)
# top_loadings_all$PC1 %>% head(n = 20)
# top_loadings_pos$PC1 %>% head(n = 20)
# top_loadings_neg$PC1 %>% head(n = 20)


#  Analyze positive, negative loadings on axes of biplots ---------------------
#+ Look at the top 15 per axis
images <- list()
mat <- combn(PCs, 2)
for(i in 1:ncol(mat)) {
    # i <- 1
    j <- mat[, i]
    
    PC_x <- x_label <- j[1]
    PC_y <- y_label <- j[2]
    
    images[[paste0("PCAtools.", PC_x, ".v.", PC_y)]] <- plot_biplot(
        pca = obj_pca,
        PC_x = PC_x,
        PC_y = PC_y,
        loadings_show = FALSE,
        loadings_n = 0,
        meta_color = "strain",
        meta_shape = "replicate",
        x_min = -100,
        x_max = 100,
        y_min = -100,
        y_max = 100
    )
    #  x and y ranges for non-normalized counts
    #+ x_min = -200000,
    #+ x_max = 200000,
    #+ y_min = -200000,
    #+ y_max = 200000
    #+
    #+ x and y ranges for rlog-normalized counts
    #+ x_min = -50,
    #+ x_max = 50,
    #+ y_min = -50,
    #+ y_max = 50
    #+
    #+ x and y ranges for GeTMM-normalized counts
    #+ x_min = -50000,
    #+ x_max = 50000,
    #+ y_min = -50000,
    #+ y_max = 50000
    #+
    #+ x and y ranges for TPM-normalized counts
    #+ x_min = -10000,
    #+ x_max = 10000,
    #+ y_min = -10000,
    #+ y_max = 10000
    
    #DECISION For now, go with rlog and TPM; continue to test all four
    
    images[[paste0("KA.", PC_x, ".v.", PC_y)]] <-
        plot_pos_neg_loadings_each_axis(
            df_all = loadings,
            df_pos = top_loadings_pos,
            df_neg = top_loadings_neg,
            PC_x = PC_x,
            PC_y = PC_y,
            row_start = 1,
            row_end = 15,  # 30
            x_min = -0.1,
            x_max = 0.1,
            y_min = -0.1,
            y_max = 0.1,
            x_nudge = 0.02,
            y_nudge = 0.04,
            x_label = x_label,
            y_label = y_label,
            col_line_pos = "black",
            col_line_neg = "red",
            col_seg_pos = "grey",
            col_seg_neg = "grey"
        )
    #  x and y ranges (etc.) for non-normalized counts (messy)
    #+ x_min = -0.75,
    #+ x_max = 0.75,
    #+ y_min = -0.33,
    #+ y_max = 0.33,
    #+ x_nudge = 0.02,
    #+ y_nudge = 0.04,
    #+
    #  x and y ranges (etc.) for rlog-normalized counts (nice and clean)
    #+ x_min = -0.1,
    #+ x_max = 0.1,
    #+ y_min = -0.1,
    #+ y_max = 0.1,
    #+ x_nudge = 0.02,
    #+ y_nudge = 0.04,
    #+
    #+ x and y ranges (etc.) for GeTMM-normalized counts (a bit messy)
    #+ x_min = -0.5,
    #+ x_max = 0.5,
    #+ y_min = -0.5,
    #+ y_max = 0.5,
    #+ x_nudge = 0.04,
    #+ y_nudge = 0.02,
    #+
    #+ x and y ranges (etc.) for TPM-normalized counts (a bit less messy)
    #+ x_min = -0.5,
    #+ x_max = 0.5,
    #+ y_min = -0.5,
    #+ y_max = 0.5,
    #+ x_nudge = 0.04,
    #+ y_nudge = 0.02,
    
    images[[paste0("KA.", PC_x, ".v.", PC_y)]]
}

#  How do things look?
images$PCAtools.PC1.v.PC2

images$KA.PC1.v.PC2$PC_x_pos

images$KA.PC1.v.PC2$PC_x_neg

images$KA.PC1.v.PC2$PC_y_pos

images$KA.PC1.v.PC2$PC_y_neg

# images$PCAtools.PC1.v.PC3
# images$KA.PC1.v.PC3
# images$PCAtools.PC1.v.PC4
# images$KA.PC1.v.PC4
# images$PCAtools.PC2.v.PC3
# images$KA.PC2.v.PC3


Part 2

# for(i in 1:length(names(images))) {
#     # i <- 2
#     vector_names <- names(images) %>% stringr::str_split("\\.")
#     
#     if(vector_names[[i]][1] == "PCAtools") {
#         save_title <- paste0("panel-plot", ".", names(images)[i], ".pdf")
#         ggplot2::ggsave(
#             paste0(args$directory_out, "/", save_title), images[[i]]
#         )
#     } else if(vector_names[[i]][1] == "KA") {
#         save_title <- paste0(
#             "panel-plot", ".", names(images)[i], ".1-x-positive.pdf"
#         )
#         ggplot2::ggsave(
#             paste0(args$directory_out, "/", save_title), images[[i]][[1]]
#         )
#         
#         save_title <- paste0(
#             "panel-plot", ".", names(images)[i], ".2-y-positive.pdf"
#         )
#         ggplot2::ggsave(
#             paste0(args$directory_out, "/", save_title), images[[i]][[2]]
#         )
#         
#         save_title <- paste0(
#             "panel-plot", ".", names(images)[i], ".3-x-negative.pdf"
#         )
#         ggplot2::ggsave(
#             paste0(args$directory_out, "/", save_title), images[[i]][[3]]
#         )
#         
#         save_title <- paste0(
#             "panel-plot", ".", names(images)[i], ".4-y-negative.pdf"
#         )
#         ggplot2::ggsave(
#             paste0(args$directory_out, "/", save_title), images[[i]][[4]]
#         )
#     }
# }
#TODO Work up some logic for outfile names, location(s) for outfiles


#  Plot the top features on an axis of component loading range ----------------
#+ ...to visualize the top variables (features) that drive variance among
#+ principal components of interest
p_loadings <- PCAtools::plotloadings(
    obj_pca,
    components = getComponents(obj_pca, 1),
    # components = getComponents(obj_pca, 1:5),
    rangeRetain = 0.05,
    absolute = FALSE,
    col = c("#785EF075", "#FFFFFF75", "#FE610075"),
    title = "Loadings plot",
    subtitle = "Top 5% of variables (i.e., features)",
    # shapeSizeRange = c(4, 16),
    borderColour = "#000000",
    borderWidth = 0.2,
    gridlines.major = TRUE,
    gridlines.minor = TRUE,
    axisLabSize = 10,
    labSize = 3,  # label_size
    drawConnectors = TRUE,
    widthConnectors = 0.2,
    typeConnectors = 'closed',
    colConnectors = 'black'
) +
    # ggplot2::coord_flip() +
    theme_slick_no_legend
p_loadings

#TODO Work up some logic for saving the plot


#  Evaluate correlations between PCs and model variables ----------------------
#+ Answer, "What is driving biologically significant variance in our data?"
PC_cor <- PCAtools::eigencorplot(
    obj_pca,
    components = PCAtools::getComponents(obj_pca, 1:5),
    metavars = c("strain", "replicate"),
    # metavars = c("strain", "replicate", "sample_name"),
    col = c("#785EF075", "#648FFF75", "#FFFFFF75", "#FFB00075", "#FE610075"),
    scale = FALSE,
    corFUN = "pearson",
    corMultipleTestCorrection = "BH",
    plotRsquared = TRUE,
    colFrame = "#FFFFFF",
    main = bquote(Pearson ~ r^2 ~ correlates),
    # main = "PC Pearson r-squared correlates",
    fontMain = 1,
    titleX = "Principal components",
    fontTitleX = 1,
    fontLabX = 1,
    titleY = "Model variables",
    rotTitleY = 90,
    fontTitleY = 1,
    fontLabY = 1
)
Warning: strain is not numeric - please check the source data as non-numeric variables will be coerced to numericWarning: replicate is not numeric - please check the source data as non-numeric variables will be coerced to numeric
PC_cor



#  Get lists of top loadings for GO analyses ----------------------------------
# for(i in c("PC1", "PC2", "PC3", "PC4")) {
for(i in c("PC1", "PC2")) {
    # i <- "PC1"
    #  Positive
    loadings_pos_PC <- rownames(top_loadings_pos[[i]])[1:500]
    save_title_pos_PC <- paste0(
        "top-500.",
        stringr::str_replace_all(get_name_of_var(loadings_pos_PC), "_", "-"),
        ".", i, ".txt"
    )
    # readr::write_tsv(
    #     dplyr::as_tibble(loadings_pos_PC),
    #     paste0(args$directory_out, "/", save_title_pos_PC),
    #     col_names = FALSE
    # )
    #TODO Work up some logic for location(s) for outfiles
    
    #  Negative
    loadings_neg_PC <- rownames(top_loadings_neg[[i]])[1:500]
    save_title_neg_PC <- paste0(
        "top-500.",
        stringr::str_replace_all(get_name_of_var(loadings_neg_PC), "_", "-"),
        ".", i, ".txt"
    )
    # readr::write_tsv(
    #     dplyr::as_tibble(loadings_neg_PC),
    #     paste0(args$directory_out, "/", save_title_neg_PC),
    #     col_names = FALSE
    # )
    #TODO Work up some logic for location(s) for outfiles
}



II. Run analyses with S. cerevisae features only

Perform size-factor estimation

Here, we subset out the K. lactis features. Thus, we are using only S. cerevisiae features in the size-factor estimation. No control genes are used.

dds_SC <- BiocGenerics::estimateSizeFactors(
    dds[dds@rowRanges$genome != "K_lactis", ]
)
dds_SC@colData
DataFrame with 5 rows and 11 columns
                                          strain    state     time      kit transcription    auxin
                                        <factor> <factor> <factor> <factor>      <factor> <factor>
n3-d_Q_day7_tcn_N_aux-T_tc-F_rep1_tech1     n3-d        Q     day7      tcn             N    aux-T
n3-d_Q_day7_tcn_N_aux-T_tc-F_rep2_tech1     n3-d        Q     day7      tcn             N    aux-T
n3-d_Q_day7_tcn_N_aux-T_tc-F_rep3_tech1     n3-d        Q     day7      tcn             N    aux-T
o-d_Q_day7_tcn_N_aux-T_tc-F_rep1_tech1      o-d         Q     day7      tcn             N    aux-T
o-d_Q_day7_tcn_N_aux-T_tc-F_rep2_tech1      o-d         Q     day7      tcn             N    aux-T
                                        timecourse replicate technical              sample_name
                                          <factor>  <factor>  <factor>                 <factor>
n3-d_Q_day7_tcn_N_aux-T_tc-F_rep1_tech1       tc-F      rep1     tech1 CT8_7716_pIAA_Q_Nascent 
n3-d_Q_day7_tcn_N_aux-T_tc-F_rep2_tech1       tc-F      rep2     tech1 CT10_7718_pIAA_Q_Nascent
n3-d_Q_day7_tcn_N_aux-T_tc-F_rep3_tech1       tc-F      rep3     tech1 CT6_7714_pIAA_Q_Nascent 
o-d_Q_day7_tcn_N_aux-T_tc-F_rep1_tech1        tc-F      rep1     tech1 CT2_6125_pIAA_Q_Nascent 
o-d_Q_day7_tcn_N_aux-T_tc-F_rep2_tech1        tc-F      rep2     tech1 CT4_6126_pIAA_Q_Nascent 
                                        sizeFactor
                                         <numeric>
n3-d_Q_day7_tcn_N_aux-T_tc-F_rep1_tech1   2.350752
n3-d_Q_day7_tcn_N_aux-T_tc-F_rep2_tech1   1.858782
n3-d_Q_day7_tcn_N_aux-T_tc-F_rep3_tech1   2.518477
o-d_Q_day7_tcn_N_aux-T_tc-F_rep1_tech1    0.333973
o-d_Q_day7_tcn_N_aux-T_tc-F_rep2_tech1    0.289205
# n3-d Q N rep1 1.444025
# n3-d Q N rep2 1.119446
# n3-d Q N rep3 1.547506
# o-d Q N rep1 0.772653
# o-d Q N rep2 0.526895


Run DESeq2

Call DESeq2 using default parameters

dds_SC <- DESeq2::DESeq(dds_SC)

#  Check model information
DESeq2::resultsNames(dds_SC)[2]
#  [1] "strain_o.d_vs_n3.d"  #HERE
#+ Thus, the model varies on strain, OsTIR-depletion is the numerator,
#+ Nab3-depletion is the denominator
#+     - Numerator: "top" in MA plots, "right" in volcano plots
#+     - Denominator: "bottom" in MA plots, "left" in volcano plots


Call DESeq2::results()


Make an MA plot that colors features by independent filtering

Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
Please use `linewidth` instead.


Make a volcano plot



III. Run analyses with K. lactis features only

Perform size-factor estimation

Here, we subset out—i.e., remove—the S. cerevisiae features and are thus only analyzing K. lactis features, using all K. lactis features in the size-factor estimation.

dds_KL <- BiocGenerics::estimateSizeFactors(
    dds[dds@rowRanges$genome != "S_cerevisiae", ]
)
dds_KL@colData
# n3-d Q N rep1 0.907373
# n3-d Q N rep2 1.034913
# n3-d Q N rep3 0.944618
# o-d Q N rep1 1.001126
# o-d Q N rep2 1.130992


Run DESeq2

Call DESeq2 using default parameters

dds_KL <- DESeq2::DESeq(dds_KL)

#  Check model information
DESeq2::resultsNames(dds_KL)[2]
#  [1] "strain_o.d_vs_n3.d"  #HERE
#+ Thus, the model varies on strain, OsTIR-depletion is the numerator,
#+ Nab3-depletion is the denominator
#+     - Numerator: "top" in MA plots, "right" in volcano plots
#+     - Denominator: "bottom" in MA plots, "left" in volcano plots


Call DESeq2::results()


Make an MA plot that colors features by independent filtering


Make a volcano plot



IV. Run analyses of S.C. in which all K.L. are controlGenes

Perform size-factor estimation

To run analyses using all K.lactis features as controlGenes, we use a logical vector (a vector composed of elements with values of either TRUE or FALSE) obtained from parsing the rowRanges dataframe within the dds object. In essence, we’re saying, “Return TRUE if the rowRanges variable genome has a value of K_lactis; otherwise, return FALSE.” Then, BiocGenerics::estimateSizeFactors() is using the values associated with those TRUEs to isolate the counts for K. lactis-specific features, in turn using those values to calculate size factors.

#  Recalculate size factors using K. lactis features as `controlGenes`
dds_SC.ctrl_KL <- BiocGenerics::estimateSizeFactors(
    dds,
    controlGenes = (dds@rowRanges$genome == "K_lactis")
)
dds_SC.ctrl_KL@colData
#  Using all of the K. lactis features as `controlGenes`
# n3-d Q N rep1 0.907373
# n3-d Q N rep2 1.034913
# n3-d Q N rep3 0.944618
# o-d Q N rep1 1.001126
# o-d Q N rep2 1.130992


Run DESeq2

Call DESeq2 using default parameters

Since we’ve already calculated the size factors, I think we can exclude K. lactis features from our work from here on out. We have to do some index subsetting to accomplish this (see below).

dds_SC.ctrl_KL <- DESeq2::DESeq(
    dds_SC.ctrl_KL[dds_SC.ctrl_KL@rowRanges$genome != "K_lactis", ]
)

#  Check model information
DESeq2::resultsNames(dds_SC.ctrl_KL)[2]
#  [1] "strain_o.d_vs_n3.d"  #HERE
#+ Thus, the model varies on strain, OsTIR-depletion is the numerator,
#+ Nab3-depletion is the denominator
#+     - Numerator: "top" in MA plots, "right" in volcano plots
#+     - Denominator: "bottom" in MA plots, "left" in volcano plots


Call DESeq2::results()


Make an MA plot that colors features by independent filtering

Make a volcano plot


LS0tCnRpdGxlOiAid29ya19ub3JtYWxpemF0aW9uLWV0Y19yb3VnaC1kcmFmdF93aWxkLXR5cGVfdmFyeS1vbi1zdGF0ZV9hbnRpc2Vuc2UiCmF1dGhvcjogIktBIgplbWFpbDogImthbGF2YXR0QGZyZWRodXRjaC5vcmciCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KPGJyIC8+CgojIyBQcmVwYXJlIGRhdGEgZm9yIHZhcmlvdXMgREdFIGFuYWx5c2VzCiMjIyBHZXQgc2l0dWF0ZWQKIyMjIyBTZXQgd29ya2luZyBkaXJlY3RvcnkgKGB3ZGApCmBgYHtyIFNldCB3b3JraW5nIGRpcmVjdG9yeSwgZWNobz1GQUxTRSwgcmVzdWx0cz0naGlkZScsIG1lc3NhZ2U9RkFMU0V9CiMgcF9sb2NhbCA8LSAiL1VzZXJzL2thbGF2YXR0YW0vRHJvcGJveC9GSENDIiAgIyBLcmlzTWFjCnBfbG9jYWwgPC0gIi9Vc2Vycy9rYWxhdmF0dC9wcm9qZWN0cy1ldGMiICAjIFdvcmtNYWMKcF93ZCA8LSAiMjAyMl90cmFuc2NyaXB0b21lLWNvbnN0cnVjdGlvbi9yZXN1bHRzLzIwMjMtMDIxNSIKI05PVEUgMS8zIEFsaXNvbjogeW91IGNhbiBhZGp1c3QgJ3BfbG9jYWwnIG9yICdwX3dkJyAocGF0aCB0byB3b3JraW5nIGRpcmVjdG9yeSAKI05PVEUgMi8zIG9uIHlvdXIgcGVyc29uYWwgb3Igd29yayBjb21wdXRlciApOyBJIGhhdmUgdHdvIHBhdGhzIGhlcmUgd2l0aCBvbmUKI05PVEUgMy8zIGNvbW1lbnRlZCBvdXQgZGVwZW5kaW5nIG9uIHdoaWNoIGNvbXB1dGVyIEkgYW0gdXNpbmcKCnNldHdkKHBhc3RlKHBfbG9jYWwsIHBfd2QsIHNlcCA9ICIvIikpCmdldHdkKCkKCnJtKHBfbG9jYWwsIHBfd2QpCmBgYAo8YnIgLz4KCiMjIyMgTG9hZCBuZWNlc3NhcnkgbGlicmFyaWVzCmBgYHtyIExvYWQgbmVjZXNzYXJ5IGxpYnJhcmllcywgZWNobz1GQUxTRSwgcmVzdWx0cz0naGlkZScsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmxpYnJhcnkoREVTZXEyKQpsaWJyYXJ5KGVkZ2VSKQpsaWJyYXJ5KEVuaGFuY2VkVm9sY2FubykKbGlicmFyeShHZW5vbWljUmFuZ2VzKQpsaWJyYXJ5KGdncmVwZWwpCmxpYnJhcnkoSVJhbmdlcykKbGlicmFyeShQQ0F0b29scykKbGlicmFyeShyZWFkeGwpCmxpYnJhcnkodGlkeXZlcnNlKQpgYGAKPGJyIC8+CgojIyMjIFNldCBvcHRpb25zCi0gVXNlIG5vcm1hbCBudW1iZXJzIGluc3RlYWQgb2YgZGVmYXVsdCBzY2llbnRpZmljIG51bWJlcnMgaW4gcGxvdHMKLSBEbyBub3QgbGltaXQgbnVtYmVyIG9mIG92ZXJsYXBzIHdoZW4gaW5jbHVkaW5nIGxhYmVscyBpbiBwbG90cwpgYGB7ciBTZXQgb3B0aW9ucywgcmVzdWx0cz0naGlkZScsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9Cm9wdGlvbnMoc2NpcGVuPTk5OSkKb3B0aW9ucyhnZ3JlcGVsLm1heC5vdmVybGFwcyA9IEluZikKYGBgCjxiciAvPgoKIyMjIyBJbml0aWFsaXplIG5lY2Vzc2FyeSBmdW5jdGlvbnMKYGBge3IgSW5pdGlhbGl6ZSBuZWNlc3NhcnkgZnVuY3Rpb25zLCBlY2hvPUZBTFNFLCByZXN1bHRzPSdoaWRlJywgbWVzc2FnZT1GQUxTRX0Kc3BsaXRfaXNvbGF0ZV9jb252ZXJ0IDwtIGZ1bmN0aW9uKGluX3ZlY3RvciwgZmllbGQsIGNvbHVtbl9uYW1lKSB7CiAgICAjIFRha2UgaW4gYSBjaGFyYWN0ZXIgdmVjdG9yIG9mIFMyODhDIFI2NC0xLTEgZmVhdHVyZSBuYW1lcyBhbmQgc3BsaXQKICAgICMgZWxlbWVudHMgYXQgdGhlIHVuZGVyc2NvcmVzIHRoYXQgc2VwYXJhdGUgZmVhdHVyZSBuYW1lcyBmcm9tCiAgICAjIGNsYXNzaWZpY2F0aW9ucywgZS5nLiwgIllFUjA0M19tUk5BLUUxIiBpcyBzcGxpdCBhdCB0aGUgdW5kZXJzY29yZS4gVXNlcgogICAgIyBoYXMgdGhlIG9wdGlvbiB0byByZXR1cm4gZWl0aGVyIHRoZSBmaXJzdCAoZmVhdHVyZSBuYW1lKSBvciBzZWNvbmQKICAgICMgKGNsYXNzaWZpY2F0aW9uKSB2YWx1ZSBpbiBhIHRpYmJsZSBkYXRhIHR5cGUuIFVzZXIgbXVzdCBhbHNvIGlucHV0IGEKICAgICMgbmFtZSBmb3IgdGhlIGNvbHVtbiBpbiB0aGUgdGliYmxlLgogICAgIwogICAgIyA6cGFyYW0gaW5fdmVjdG9yOiBjaGFyYWN0ZXIgdmVjdG9yIG9mIFMyODhDIFI2NC0xLTEgZmVhdHVyZSBuYW1lcyBbdmVjXQogICAgIyA6cGFyYW0gZmllbGQ6IGZpcnN0IG9yIHNlY29uZCBzdHJpbmcgc2VwYXJhdGVkIGJ5IHVuZGVyc2NvcmUKICAgICMgICAgICAgICAgICAgICBbaW50ID0gMSB8IGludCA9IDJdCiAgICAjIDpwYXJhbSBjb2x1bW5fbmFtZTogbmFtZSBvZiBjb2x1bW4gaW4gdGliYmxlIFtjaHJdCiAgICAjIDpyZXR1cm4gb3V0X2RmOiB0aWJibGUgb2YgZmlyc3Qgb3Igc2Vjb25kIHN0cmluZ3Mgc2VwYXJhdGVkIGJ5IHVuZGVyc2NvcmUKICAgICMgICAgICAgICAgICAgICAgIFt0YmxdCiAgICBvdXRfZGYgPC0gaW5fdmVjdG9yICU+JQogICAgICAgIHN0cmluZ3I6OnN0cl9zcGxpdCguLCBjKCJfIikpICU+JQogICAgICAgIHNhcHBseSguLCAiWyIsIGZpZWxkKSAlPiUKICAgICAgICBhcy5kYXRhLmZyYW1lKCkgJT4lCiAgICAgICAgdGliYmxlOjphc190aWJibGUoKQogICAgCiAgICBjb2xuYW1lcyhvdXRfZGYpIDwtIGNvbHVtbl9uYW1lCiAgICAKICAgIHJldHVybihvdXRfZGYpCn0KI1RPRE8gTm90ZSB3aGVyZSB0aGlzIGZ1bmN0aW9uIGlzIGJlaW5nIHVzZWQKI1RPRE8gQWRkIHJldHVybiBkZXNjcmlwdGlvbgoKCnBsb3Rfdm9sY2FubyA8LSBmdW5jdGlvbigKICAgIHRhYmxlLCBsYWJlbCwgc2VsZWN0aW9uLCBsYWJlbF9zaXplLCBwX2N1dG9mZiwgRkNfY3V0b2ZmLAogICAgeGxpbSwgeWxpbSwgY29sb3IsIHRpdGxlLCBzdWJ0aXRsZSwgLi4uCikgewogICAgI1RPRE8gV3JpdGUgYSBkZXNjcmlwdGlvbiBvZiB0aGlzIGZ1bmN0aW9uCiAgICAjCiAgICAjIDpwYXJhbSB0YWJsZTogZGF0YWZyYW1lIG9mIHRlc3Qgc3RhdGlzdGljcyBbZGZdCiAgICAjIDpwYXJhbSBsYWJlbDogY2hhcmFjdGVyIHZlY3RvciBvZiBhbGwgdmFyaWFibGUgbmFtZXMgaW4gcGFyYW0gdGFibGUgW3ZlY10KICAgICMgOnBhcmFtIHNlbGVjdGlvbjogY2hhcmFjdGVyIHZlY3RvciBvZiBzZWxlY3RlZCB2YXJpYWJsZSBuYW1lcyBpbiBwYXJhbQogICAgIyAgICAgICAgICAgICAgICAgICB0YWJsZSBbdmVjXQogICAgIyA6cGFyYW0gbGFiZWxfc2l6ZTogc2l6ZSBvZiBsYWJlbCBmb250IFtmbG9hdF0KICAgICMgOnBhcmFtIHBfY3V0b2ZmOiBjdXQtb2ZmIGZvciBzdGF0aXN0aWNhbCBzaWduaWZpY2FuY2U7IGEgaG9yaXpvbnRhbCBsaW5lCiAgICAjICAgICAgICAgICAgICAgICAgd2lsbCBiZSBkcmF3biBhdCAtbG9nMTAocEN1dG9mZik7IHAgaXMgYWN0dWFsbHkgcGFkagogICAgIyAgICAgICAgICAgICAgICAgIFtmbG9hdF0KICAgICMgOnBhcmFtIEZDX2N1dG9mZjogY3V0LW9mZiBmb3IgYWJzb2x1dGUgbG9nMiBmb2xkLWNoYW5nZTsgdmVydGljYWwgbGluZXMKICAgICMgICAgICAgICAgICAgICAgICAgd2lsbCBiZSBkcmF3biBhdCB0aGUgbmVnYXRpdmUgYW5kIHBvc2l0aXZlIHZhbHVlcyBvZgogICAgIyAgICAgICAgICAgICAgICAgICBsb2cyRkNjdXRvZmYKICAgICMgICAgICAgICAgICAgICAgICBbZmxvYXRdCiAgICAjIDpwYXJhbSB4bGltOiBsaW1pdHMgb2YgdGhlIHgtYXhpcyBbZmxvYXRdCiAgICAjIDpwYXJhbSB5bGltOiBsaW1pdHMgb2YgdGhlIHktYXhpcyBbZmxvYXRdCiAgICAjIDpwYXJhbSBjb2xvcjogY29sb3Igb2YgREVHcywgZS5nLiwgJyM1MkJFOUInIFtoZXhdCiAgICAjIDpwYXJhbSB0aXRsZTogcGxvdCB0aXRsZSBbY2hyXQogICAgIyA6cGFyYW0gc3VidGl0bGU6IHBsb3Qgc3VidGl0bGUgW2Nocl0KICAgICMgOnJldHVybiB2b2xjYW5vOiAuLi4KICAgIHZvbGNhbm8gPC0gRW5oYW5jZWRWb2xjYW5vOjpFbmhhbmNlZFZvbGNhbm8oCiAgICAgICAgdG9wdGFibGUgPSB0YWJsZSwKICAgICAgICBsYWIgPSBsYWJlbCwKICAgICAgICBzZWxlY3RMYWIgPSBzZWxlY3Rpb24sCiAgICAgICAgeCA9ICJsb2cyRm9sZENoYW5nZSIsCiAgICAgICAgeSA9ICJwYWRqIiwKICAgICAgICB4bGFiID0gImxvZzIoRkMpIiwKICAgICAgICB5bGFiID0gIi1sb2cxMChwYWRqKSIsCiAgICAgICAgcEN1dG9mZiA9IHBfY3V0b2ZmLAogICAgICAgIHBDdXRvZmZDb2wgPSAicGFkaiIsCiAgICAgICAgRkNjdXRvZmYgPSBGQ19jdXRvZmYsCiAgICAgICAgeGxpbSA9IHhsaW0sCiAgICAgICAgeWxpbSA9IHlsaW0sCiAgICAgICAgY3V0b2ZmTGluZVR5cGUgPSAiZGFzaGVkIiwKICAgICAgICBjdXRvZmZMaW5lV2lkdGggPSAwLjIsCiAgICAgICAgcG9pbnRTaXplID0gMSwKICAgICAgICBzaGFwZSA9IDE2LAogICAgICAgIGNvbEFscGhhID0gMC4yNSwKICAgICAgICBjb2wgPSBjKCcjRDNEM0QzJywgJyNEM0QzRDMnLCAnI0QzRDNEMycsIGNvbG9yKSwKICAgICAgICB0aXRsZSA9IE5VTEwsCiAgICAgICAgc3VidGl0bGUgPSBOVUxMLAogICAgICAgIGNhcHRpb24gPSBOVUxMLAogICAgICAgIGJvcmRlckNvbG91ciA9ICIjMDAwMDAwIiwKICAgICAgICBib3JkZXJXaWR0aCA9IDAuMiwKICAgICAgICBncmlkbGluZXMubWFqb3IgPSBUUlVFLAogICAgICAgIGdyaWRsaW5lcy5taW5vciA9IFRSVUUsCiAgICAgICAgYXhpc0xhYlNpemUgPSAxMCwKICAgICAgICBsYWJTaXplID0gbGFiZWxfc2l6ZSwKICAgICAgICBib3hlZExhYmVscyA9IFRSVUUsCiAgICAgICAgcGFyc2VMYWJlbHMgPSBUUlVFLAogICAgICAgIGRyYXdDb25uZWN0b3JzID0gVFJVRSwKICAgICAgICB3aWR0aENvbm5lY3RvcnMgPSAwLjIsCiAgICAgICAgY29sQ29ubmVjdG9ycyA9ICdibGFjaycsCiAgICAgICAgbWF4Lm92ZXJsYXBzID0gSW5mCiAgICApICsKICAgICAgICB0aGVtZV9zbGlja19ub19sZWdlbmQgKwogICAgICAgIGdncGxvdDI6OmdndGl0bGUodGl0bGUsIHN1YnRpdGxlID0gc3VidGl0bGUpCiAgICByZXR1cm4odm9sY2FubykKfQojVE9ETyBOb3RlIHdoZXJlIHRoaXMgZnVuY3Rpb24gaXMgYmVpbmcgdXNlZAojVE9ETyBBZGQgcmV0dXJuIGRlc2NyaXB0aW9uCgoKc2F2ZV92b2xjYW5vIDwtIGZ1bmN0aW9uKHBsb3QsIGZpbGUsIHdpZHRoLCBoZWlnaHQpIHsKICAgICNUT0RPIFdyaXRlIGEgZGVzY3JpcHRpb24gb2YgdGhpcyBmdW5jdGlvbgogICAgIwogICAgIyA6cGFyYW0gcGxvdDogLi4uCiAgICAjIDpwYXJhbSBmaWxlOiAuLi4KICAgICMgOnBhcmFtIHdpZHRoOiAuLi4KICAgICMgOnBhcmFtIGhlaWdodDogLi4uCiAgICAjIDpyZXR1cm46IC4uLgogICAgZ2dwbG90Mjo6Z2dzYXZlKAogICAgICAgIHBsb3QsCiAgICAgICAgZmlsZW5hbWUgPSBmaWxlLAogICAgICAgIGRldmljZSA9ICJwZGYiLAogICAgICAgIGggPSB3aWR0aCwKICAgICAgICB3ID0gaGVpZ2h0LAogICAgICAgIHVuaXRzID0gImluIgogICAgKQp9CiNUT0RPIE5vdGUgd2hlcmUgdGhpcyBmdW5jdGlvbiBpcyBiZWluZyB1c2VkCiNUT0RPIEFkZCByZXR1cm4gZGVzY3JpcHRpb24KCgpnZXRfbmFtZV9vZl92YXIgPC0gZnVuY3Rpb24odikgewogICAgI1RPRE8gV3JpdGUgYSBkZXNjcmlwdGlvbiBvZiB0aGlzIGZ1bmN0aW9uCiAgICAjCiAgICAjIDpwYXJhbSB2OiAuLi4KICAgICMgOnJldHVybiB2OiAuLi4KICAgIHJldHVybihkZXBhcnNlKHN1YnN0aXR1dGUodikpKQp9CiNUT0RPIE5vdGUgd2hlcmUgdGhpcyBmdW5jdGlvbiBpcyBiZWluZyB1c2VkCgoKZ2V0X3RvcF9sb2FkaW5ncyA8LSBmdW5jdGlvbih4LCB5LCB6LCBhKSB7CiAgICAjVE9ETyBXcml0ZSBhIGRlc2NyaXB0aW9uIG9mIHRoaXMgZnVuY3Rpb24KICAgICMKICAgICMgOnBhcmFtIHg6IGRhdGFmcmFtZSBvZiBQQyBsb2FkaW5ncyA8ZGF0YS5mcmFtZT4KICAgICMgOnBhcmFtIHk6IGNoYXJhY3RlciBlbGVtZW50IGZvciBjb2x1bW4gaW4gZGF0YWZyYW1lIHggPGNocj4KICAgICMgOnBhcmFtIHo6IHdoZXRoZXIgdG8gc2VsZWN0IGFsbCBsb2FkaW5ncyBzb3J0ZWQgZnJvbSBsYXJnZXN0IHRvIHNtYWxsZXN0CiAgICAjICAgICAgICAgICBhYnNvbHV0ZSB2YWx1ZSAoJ2FsbCcpLCBwb3NpdGl2ZSBsb2FkaW5ncyBzb3J0ZWQgZnJvbSBsYXJnZXN0CiAgICAjICAgICAgICAgICB0byBzbWFsbGVzdCB2YWx1ZSAoJ3BvcycpLCBvciBuZWdhdGl2ZSBsb2FkaW5ncyBzb3J0ZWQgZnJvbQogICAgIyAgICAgICAgICAgbGFyZ2VzdCB0byBzbWFsbGVzdCBhYnNvbHV0ZSB2YWx1ZSAoJ25lZycpIDxzdHI+CiAgICAjIDpwYXJhbSBhOiB3aGV0aGVyIG9yIG5vdCB0byBrZWVwICdzaWduJyBhbmQgJ2FicycgY29sdW1ucyBhZGRlZCBpbiB0aGUKICAgICMgICAgICAgICAgIGNvdXJzZSBvZiBwcm9jZXNzaW5nIHRoZSBkYXRhZnJhbWUgPGxvZ2ljYWw+CiAgICAjIDpyZXR1cm4gYjogLi4uCiAgICBiIDwtIGFzLmRhdGEuZnJhbWUoeFtbeV1dKQogICAgcm93bmFtZXMoYikgPC0gcm93bmFtZXMoeCkKICAgIGNvbG5hbWVzKGIpIDwtIHkKICAgIAogICAgYltbInNpZ24iXV0gPC0gaWZlbHNlKAogICAgICAgIGJbW3ldXSA+IDAsCiAgICAgICAgInBvcyIsCiAgICAgICAgaWZlbHNlKAogICAgICAgICAgICBiW1t5XV0gPT0gMCwKICAgICAgICAgICAgInplcm8iLAogICAgICAgICAgICAibmVnIgogICAgICAgICkKICAgICkKICAgIAogICAgYltbImFicyJdXSA8LSBhYnMoYltbeV1dKQogICAgCiAgICBpZih6ID09ICJhbGwiKSB7CiAgICAgICAgYiA8LSBkcGx5cjo6YXJyYW5nZShiLCBieSA9IGRlc2MoYWJzKSkKICAgIH0gZWxzZSBpZih6ID09ICJwb3MiKSB7CiAgICAgICAgYiA8LSBiW2JbW3ldXSA+IDAsIF0gJT4lIGRwbHlyOjphcnJhbmdlKC4sIGJ5ID0gZGVzYyhhYnMpKQogICAgfSBlbHNlIGlmKHogPT0gIm5lZyIpIHsKICAgICAgICBiIDwtIGJbYltbeV1dIDwgMCwgXSAlPiUgZHBseXI6OmFycmFuZ2UoLiwgYnkgPSBkZXNjKGFicykpCiAgICB9IGVsc2UgewogICAgICAgIHN0b3AocGFzdGUwKCJTdG9wcGluZzogcGFyYW0geiBtdXN0IGJlIGVpdGhlciAnYWxsJywgJ3BvcycsIG9yICduZWcnIikpCiAgICB9CiAgICAKICAgIGlmKGlzVFJVRShhKSkgewogICAgICAgIHBhc3RlMCgiUmV0YWluaW5nICdzaWduJyBhbmQgJ2FicycgY29sdW1ucyIpCiAgICB9IGVsc2UgaWYoaXNGQUxTRShhKSkgewogICAgICAgIGIgPC0gYiAlPiUgZHBseXI6OnNlbGVjdCgtYyhzaWduLCBhYnMpKQogICAgfSBlbHNlIHsKICAgICAgICBzdG9wKHBhc3RlMCgiU3RvcHBpbmc6IHBhcmFtIGEgbXVzdCBiZSBlaXRoZXIgJ1RSVUUnIG9yICdGQUxTRSciKSkKICAgIH0KICAgIAogICAgcmV0dXJuKGIpCn0KI1RPRE8gTm90ZSB3aGVyZSB0aGlzIGZ1bmN0aW9uIGlzIGJlaW5nIHVzZWQKI1RPRE8gQWRkIHJldHVybiBkZXNjcmlwdGlvbgoKCnBsb3RfYmlwbG90IDwtIGZ1bmN0aW9uKAogICAgcGNhLCBQQ194LCBQQ195LAogICAgbG9hZGluZ3Nfc2hvdywgbG9hZGluZ3NfbiwKICAgIG1ldGFfY29sb3IsIG1ldGFfc2hhcGUsCiAgICB4X21pbiwgeF9tYXgsIHlfbWluLCB5X21heAopIHsKICAgICNUT0RPIFdyaXRlIGEgZGVzY3JpcHRpb24gb2YgdGhpcyBmdW5jdGlvbgogICAgIwogICAgIyA6cGFyYW0gcGNhOiAicGNhIiBsaXN0IG9iamVjdCBvYnRhaW5lZCBieSBydW5uaW5nIFBDQXRvb2xzOjpwY2EoKQogICAgIyA6cGFyYW0gUENfeDogUEMgdG8gcGxvdCBvbiB0aGUgeCBheGlzIDxjaHI+CiAgICAjIDpwYXJhbSBQQ195OiBQQyB0byBwbG90IG9uIHRoZSB5IGF4aXMgPGNocj4KICAgICMgOnBhcmFtIGxvYWRpbmdzX3Nob3c6IHdoZXRoZXIgdG8gb3ZlcmxheSBjb21wb25lbnQgbG9hZGluZ3Mgb3Igbm90IDxsZ2w+CiAgICAjIDpwYXJhbSBsb2FkaW5nc19uOiBudW1iZXIgb2YgdG9wIGxvYWRpbmdzIHRvIHNob3cgPGludCA+PSAwPgogICAgIyA6cGFyYW0gbWV0YV9jb2xvcjogY29sdW1uIGluICJwY2EiIGxpc3QgbWV0YWRhdGEgdG8gY29sb3IgYnkgPGNocj4KICAgICMgOnBhcmFtIG1ldGFfc2hhcGU6IGNvbHVtbiBpbiAicGNhIiBsaXN0IG1ldGFkYXRhIHRvIHNoYXBlIGJ5IDxjaHI+CiAgICAjIDpwYXJhbSB4X21pbjogbWluaW11bSB2YWx1ZSBvbiB4IGF4aXMgPGRibD4KICAgICMgOnBhcmFtIHhfbWF4OiBtYXhpbXVtIHZhbHVlIG9uIHggYXhpcyA8ZGJsPgogICAgIyA6cGFyYW0geV9taW46IG1pbmltdW0gdmFsdWUgb24geSBheGlzIDxkYmw+CiAgICAjIDpwYXJhbSB5X21heDogbWF4aW11bSB2YWx1ZSBvbiB5IGF4aXMgPGRibD4KICAgICMgOnBhcmFtIHRpdGxlOiB0aXRsZSBvZiBiaXBsb3QgPGRibD4KICAgICMgOnJldHVybiBpbWFnZTogLi4uCiAgICBpbWFnZSA8LSBwY2EgJT4lIAogICAgICAgIFBDQXRvb2xzOjpiaXBsb3QoCiAgICAgICAgICAgIHggPSBQQ194LAogICAgICAgICAgICB5ID0gUENfeSwKICAgICAgICAgICAgbGFiID0gTlVMTCwKICAgICAgICAgICAgc2hvd0xvYWRpbmdzID0gbG9hZGluZ3Nfc2hvdywKICAgICAgICAgICAgbnRvcExvYWRpbmdzID0gbG9hZGluZ3NfbiwKICAgICAgICAgICAgYm94ZWRMb2FkaW5nc05hbWVzID0gVFJVRSwKICAgICAgICAgICAgY29sYnkgPSBtZXRhX2NvbG9yLAogICAgICAgICAgICBzaGFwZSA9IG1ldGFfc2hhcGUsCiAgICAgICAgICAgIGVuY2lyY2xlID0gRkFMU0UsCiAgICAgICAgICAgIGVsbGlwc2UgPSBGQUxTRSwKICAgICAgICAgICAgbWF4Lm92ZXJsYXBzID0gSW5mLAogICAgICAgICAgICB4bGltID0gYyh4X21pbiwgeF9tYXgpLAogICAgICAgICAgICB5bGltID0gYyh5X21pbiwgeV9tYXgpCiAgICAgICAgKSArCiAgICAgICAgICAgIHRoZW1lX3NsaWNrCiAgICAKICAgIHJldHVybihpbWFnZSkKfQojVE9ETyBOb3RlIHdoZXJlIHRoaXMgZnVuY3Rpb24gaXMgYmVpbmcgdXNlZAojVE9ETyBBZGQgcmV0dXJuIGRlc2NyaXB0aW9uCgoKcGxvdF9wb3NfbmVnX2xvYWRpbmdzX2VhY2hfYXhpcyA8LSBmdW5jdGlvbigKICAgIGRmX2FsbCwgZGZfcG9zLCBkZl9uZWcsCiAgICBQQ194LCBQQ195LAogICAgcm93X3N0YXJ0LCByb3dfZW5kLAogICAgeF9taW4sIHhfbWF4LCB5X21pbiwgeV9tYXgsCiAgICB4X251ZGdlLCB5X251ZGdlLCB4X2xhYmVsLCB5X2xhYmVsLAogICAgY29sX2xpbmVfcG9zLCBjb2xfbGluZV9uZWcsIGNvbF9zZWdfcG9zLCBjb2xfc2VnX25lZwopIHsKICAgICNUT0RPIFdyaXRlIGEgZGVzY3JpcHRpb24gb2YgdGhpcyBmdW5jdGlvbgogICAgIwogICAgIyA6cGFyYW0gZGZfYWxsOiBkYXRhZnJhbWU6IGFsbCBsb2FkaW5ncyAoZnJvbSwgZS5nLiwgUENBdG9vbHMpCiAgICAjIDpwYXJhbSBkZl9wb3M6IGRhdGFmcmFtZTogcG9zaXRpdmUgbG9hZGluZ3Mgb3JkZXJlZCBsYXJnZXN0IHRvIHNtYWxsZXN0CiAgICAjIDpwYXJhbSBkZl9uZWc6IGRhdGFmcmFtZTogbmVnYXRpdmUgbG9hZGluZ3Mgb3JkZXJlZCBzbWFsbGVzdCB0byBsYXJnZXN0CiAgICAjIDpwYXJhbSBQQ194OiBQQyB0byBwbG90IG9uIHRoZSB4IGF4aXMKICAgICMgOnBhcmFtIFBDX3k6IFBDIHRvIHBsb3Qgb24gdGhlIHkgYXhpcwogICAgIyA6cGFyYW0gcm93X3N0YXJ0OiByb3cgZnJvbSB3aGljaCB0byBiZWdpbiBzdWJzZXR0aW5nIHRoZSBQQ3Mgb24geCBhbmQgeQogICAgIyA6cGFyYW0gcm93X2VuZDogcm93IGF0IHdoaWNoIHRvIGVuZCBzdWJzZXR0aW5nIHRoZSBQQ3Mgb24geCBhbmQgeQogICAgIyA6cGFyYW0geF9taW46IG1pbmltdW0gdmFsdWUgb24geCBheGlzIDxkYmw+CiAgICAjIDpwYXJhbSB4X21heDogbWF4aW11bSB2YWx1ZSBvbiB4IGF4aXMgPGRibD4KICAgICMgOnBhcmFtIHlfbWluOiBtaW5pbXVtIHZhbHVlIG9uIHkgYXhpcyA8ZGJsPgogICAgIyA6cGFyYW0geV9tYXg6IG1heGltdW0gdmFsdWUgb24geSBheGlzIDxkYmw+CiAgICAjIDpwYXJhbSB4X251ZGdlOiBhbW91bnQgdG8gbnVkZ2UgbGFiZWxzIG9uIHRoZSB4IGF4aXMgPGRibD4KICAgICMgOnBhcmFtIHlfbnVkZ2U6IGFtb3VudCB0byBudWRnZSBsYWJlbHMgb24gdGhlIHkgYXhpcyA8ZGJsPgogICAgIyA6cGFyYW0geF9sYWJlbDogeCBheGlzIGxhYmVsIDxjaHI+CiAgICAjIDpwYXJhbSB5X2xhYmVsOiB5IGF4aXMgbGFiZWwgPGNocj4KICAgICMgOnBhcmFtIGNvbF9saW5lX3BvczogY29sb3I6IGxpbmVzLCBhcnJvd3MgZm9yIHBvc2l0aXZlIGxvYWRpbmdzIDxjaHI+CiAgICAjIDpwYXJhbSBjb2xfbGluZV9uZWc6IGNvbG9yOiBsaW5lcywgYXJyb3dzIGZvciBuZWdhdGl2ZSBsb2FkaW5ncyA8Y2hyPgogICAgIyA6cGFyYW0gY29sX3NlZ19wb3M6IGNvbG9yOiBzZWdtZW50cyBjb25uZWN0aW5nIGFycm93aGVhZCBhbmQgdGV4dCBidWJibGUKICAgICMgICAgICAgICAgICAgICAgICAgICBmb3IgcG9zaXRpdmUgbG9hZGluZ3MgPGNocj4KICAgICMgOnBhcmFtIGNvbF9zZWdfbmVnOiBjb2xvcjogc2VnbWVudHMgY29ubmVjdGluZyBhcnJvd2hlYWQgYW5kIHRleHQgYnViYmxlCiAgICAjICAgICAgICAgICAgICAgICAgICAgZm9yIG5lZ2F0aXZlIGxvYWRpbmdzIDxjaHI+CiAgICAjIDpyZXR1cm4gaW1hZ2U6IC4uLgogICAgZmlsdGVyX3Bvc18xIDwtIHJvd25hbWVzKGRmX3Bvc1tbUENfeF1dW3Jvd19zdGFydDpyb3dfZW5kLCBdKQogICAgZmlsdGVyX3Bvc18yIDwtIHJvd25hbWVzKGRmX3Bvc1tbUENfeV1dW3Jvd19zdGFydDpyb3dfZW5kLCBdKQogICAgZmlsdGVyX25lZ18xIDwtIHJvd25hbWVzKGRmX25lZ1tbUENfeF1dW3Jvd19zdGFydDpyb3dfZW5kLCBdKQogICAgZmlsdGVyX25lZ18yIDwtIHJvd25hbWVzKGRmX25lZ1tbUENfeV1dW3Jvd19zdGFydDpyb3dfZW5kLCBdKQogICAgCiAgICBsb2FkaW5nc19maWx0ZXJfcG9zXzEgPC0gZGZfYWxsW3Jvd25hbWVzKGRmX2FsbCkgJWluJSBmaWx0ZXJfcG9zXzEsIF0KICAgIGxvYWRpbmdzX2ZpbHRlcl9wb3NfMiA8LSBkZl9hbGxbcm93bmFtZXMoZGZfYWxsKSAlaW4lIGZpbHRlcl9wb3NfMiwgXQogICAgbG9hZGluZ3NfZmlsdGVyX25lZ18xIDwtIGRmX2FsbFtyb3duYW1lcyhkZl9hbGwpICVpbiUgZmlsdGVyX25lZ18xLCBdCiAgICBsb2FkaW5nc19maWx0ZXJfbmVnXzIgPC0gZGZfYWxsW3Jvd25hbWVzKGRmX2FsbCkgJWluJSBmaWx0ZXJfbmVnXzIsIF0KICAgIAogICAgaW1hZ2VzIDwtIGxpc3QoKQogICAgaW1hZ2VzW1siUENfeF9wb3MiXV0gPC0gcGxvdF9sb2FkaW5ncygKICAgICAgICBsb2FkaW5nc19maWx0ZXJfcG9zXzEsCiAgICAgICAgbG9hZGluZ3NfZmlsdGVyX3Bvc18xW1tQQ194XV0sCiAgICAgICAgbG9hZGluZ3NfZmlsdGVyX3Bvc18xW1tQQ195XV0sCiAgICAgICAgeF9taW4sIHhfbWF4LCB5X21pbiwgeV9tYXgsIHhfbnVkZ2UsIHlfbnVkZ2UsCiAgICAgICAgeF9sYWJlbCwgeV9sYWJlbCwgY29sX2xpbmVfcG9zLCBjb2xfc2VnX3BvcwogICAgKQogICAgaW1hZ2VzW1siUENfeV9wb3MiXV0gPC0gcGxvdF9sb2FkaW5ncygKICAgICAgICBsb2FkaW5nc19maWx0ZXJfcG9zXzIsCiAgICAgICAgbG9hZGluZ3NfZmlsdGVyX3Bvc18yW1tQQ194XV0sCiAgICAgICAgbG9hZGluZ3NfZmlsdGVyX3Bvc18yW1tQQ195XV0sCiAgICAgICAgeF9taW4sIHhfbWF4LCB5X21pbiwgeV9tYXgsIHhfbnVkZ2UsIHlfbnVkZ2UsCiAgICAgICAgeF9sYWJlbCwgeV9sYWJlbCwgY29sX2xpbmVfcG9zLCBjb2xfc2VnX3BvcwogICAgKQogICAgaW1hZ2VzW1siUENfeF9uZWciXV0gPC0gcGxvdF9sb2FkaW5ncygKICAgICAgICBsb2FkaW5nc19maWx0ZXJfbmVnXzEsCiAgICAgICAgbG9hZGluZ3NfZmlsdGVyX25lZ18xW1tQQ194XV0sCiAgICAgICAgbG9hZGluZ3NfZmlsdGVyX25lZ18xW1tQQ195XV0sCiAgICAgICAgeF9taW4sIHhfbWF4LCB5X21pbiwgeV9tYXgsIC15X251ZGdlLCB4X251ZGdlLAogICAgICAgIHhfbGFiZWwsIHlfbGFiZWwsIGNvbF9saW5lX25lZywgY29sX3NlZ19uZWcKICAgICkKICAgIGltYWdlc1tbIlBDX3lfbmVnIl1dIDwtIHBsb3RfbG9hZGluZ3MoCiAgICAgICAgbG9hZGluZ3NfZmlsdGVyX25lZ18yLAogICAgICAgIGxvYWRpbmdzX2ZpbHRlcl9uZWdfMltbUENfeF1dLAogICAgICAgIGxvYWRpbmdzX2ZpbHRlcl9uZWdfMltbUENfeV1dLAogICAgICAgIHhfbWluLCB4X21heCwgeV9taW4sIHlfbWF4LCB4X251ZGdlLCAteV9udWRnZSwKICAgICAgICB4X2xhYmVsLCB5X2xhYmVsLCBjb2xfbGluZV9uZWcsIGNvbF9zZWdfbmVnCiAgICApCiAgICByZXR1cm4oaW1hZ2VzKQp9CiNUT0RPIE5vdGUgd2hlcmUgdGhpcyBmdW5jdGlvbiBpcyBiZWluZyB1c2VkCiNUT0RPIEFkZCByZXR1cm4gZGVzY3JpcHRpb24KCgpwbG90X2xvYWRpbmdzIDwtIGZ1bmN0aW9uKHgsIHksIHosIGEsIGIsIGQsIGUsIGYsIGcsIGgsIGksIGosIGspIHsKICAgICNUT0RPIFdyaXRlIGEgZGVzY3JpcHRpb24gb2YgdGhpcyBmdW5jdGlvbgogICAgIwogICAgIyA6cGFyYW0geDogZGF0YWZyYW1lIG9mIFBDIGxvYWRpbmdzIHcvZ2VuZSBuYW1lcyBhcyByb3duYW1lcyA8ZGF0YS5mcmFtZT4KICAgICMgOnBhcmFtIHk6IGNvbHVtbiBpbiBkYXRhZnJhbWUgdG8gcGxvdCBvbiB4IGF4aXMgPGRibD4KICAgICMgOnBhcmFtIHo6IGNvbHVtbiBpbiBkYXRhZnJhbWUgdG8gcGxvdCBvbiB5IGF4aXMgPGRibD4KICAgICMgOnBhcmFtIGE6IG1pbmltdW0gdmFsdWUgb24geCBheGlzIDxkYmw+CiAgICAjIDpwYXJhbSBiOiBtYXhpbXVtIHZhbHVlIG9uIHggYXhpcyA8ZGJsPgogICAgIyA6cGFyYW0gZDogbWluaW11bSB2YWx1ZSBvbiB5IGF4aXMgPGRibD4KICAgICMgOnBhcmFtIGU6IG1heGltdW0gdmFsdWUgb24geSBheGlzIDxkYmw+CiAgICAjIDpwYXJhbSBmOiBhbW91bnQgdG8gbnVkZ2UgbGFiZWxzIG9uIHRoZSB4IGF4aXMgPGRibD4KICAgICMgOnBhcmFtIGc6IGFtb3VudCB0byBudWRnZSBsYWJlbHMgb24gdGhlIHkgYXhpcyA8ZGJsPgogICAgIyA6cGFyYW0gaDogeCBheGlzIGxhYmVsIDxjaHI+CiAgICAjIDpwYXJhbSBpOiB5IGF4aXMgbGFiZWwgPGNocj4KICAgICMgOnBhcmFtIGo6IGNvbG9yIG9mIGxpbmUgYW5kIGFycm93IDxjaHI+CiAgICAjIDpwYXJhbSBrOiBjb2xvciBvZiBzZWdtZW50IGNvbm5lY3RpbmcgYXJyb3doZWFkIGFuZCB0ZXh0IGJ1YmJsZSA8Y2hyPgogICAgbCA8LSBnZ3Bsb3QyOjpnZ3Bsb3QoeCwgZ2dwbG90Mjo6YWVzKHggPSB5LCB5ID0geikpICsgICNUT0RPICNGVU5DVElPTgogICAgICAgIGdncGxvdDI6OmNvb3JkX2NhcnRlc2lhbih4bGltID0gYyhhLCBiKSwgeWxpbSA9IGMoZCwgZSkpICsKICAgICAgICBnZ3Bsb3QyOjpnZW9tX3NlZ21lbnQoCiAgICAgICAgICAgIGFlcyh4ZW5kID0gMCwgeWVuZCA9IDAsIGFscGhhID0gMC41KSwKICAgICAgICAgICAgY29sb3IgPSBqLCAKICAgICAgICAgICAgYXJyb3cgPSBnZ3Bsb3QyOjphcnJvdygKICAgICAgICAgICAgICAgIGVuZHMgPSAiZmlyc3QiLAogICAgICAgICAgICAgICAgdHlwZSA9ICJvcGVuIiwKICAgICAgICAgICAgICAgIGxlbmd0aCA9IHVuaXQoMC4xMjUsICJpbmNoZXMiKQogICAgICAgICAgICApCiAgICAgICAgKSArCiAgICAgICAgZ2dyZXBlbDo6Z2VvbV9sYWJlbF9yZXBlbCgKICAgICAgICAgICAgbWFwcGluZyA9IGdncGxvdDI6OmFlcygKICAgICAgICAgICAgICAgIGZvbnRmYWNlID0gMSwgc2VnbWVudC5jb2xvciA9IGssIHNlZ21lbnQuc2l6ZSA9IDAuMjUKICAgICAgICAgICAgKSwKICAgICAgICAgICAgbGFiZWwgPSByb3duYW1lcyh4KSwKICAgICAgICAgICAgbGFiZWwuc2l6ZSA9IDAuMDUsCiAgICAgICAgICAgIGRpcmVjdGlvbiA9ICJib3RoIiwKICAgICAgICAgICAgbnVkZ2VfeCA9IGYsICAjIDAuMDIKICAgICAgICAgICAgbnVkZ2VfeSA9IGcsICAjIDAuMDQKICAgICAgICAgICAgZm9yY2UgPSA0LAogICAgICAgICAgICBmb3JjZV9wdWxsID0gMSwKICAgICAgICAgICAgaGp1c3QgPSAwCiAgICAgICAgKSArCiAgICAgICAgZ2dwbG90Mjo6eGxhYihoKSArCiAgICAgICAgZ2dwbG90Mjo6eWxhYihpKSArCiAgICAgICAgdGhlbWVfc2xpY2tfbm9fbGVnZW5kCiAgICAKICAgIHJldHVybihsKQp9CiNUT0RPIE5vdGUgd2hlcmUgdGhpcyBmdW5jdGlvbiBpcyBiZWluZyB1c2VkCiNUT0RPIEFkZCByZXR1cm4gZGVzY3JpcHRpb24KCgojSEVSRQpkcmF3X3NjcmVlX3Bsb3QgPC0gZnVuY3Rpb24ocGNhLCBob3JuLCBlbGJvdykgewogICAgI1RPRE8gV3JpdGUgYSBkZXNjcmlwdGlvbiBvZiB0aGlzIGZ1bmN0aW9uCiAgICAjCiAgICAjIDpwYXJhbSBwY2E6ICJwY2EiIGxpc3Qgb2JqZWN0IG9idGFpbmVkIGJ5IHJ1bm5pbmcgUENBdG9vbHM6OnBjYSgpCiAgICAjIDpwYXJhbSBob3JuOiAuLi4KICAgICMgOnBhcmFtIGVsYm93OiAuLi4KICAgICMgOnJldHVybiBzY3JlZTogLi4uCiAgICBzY3JlZSA8LSBQQ0F0b29sczo6c2NyZWVwbG90KAogICAgICAgIHBjYSwKICAgICAgICBjb21wb25lbnRzID0gUENBdG9vbHM6OmdldENvbXBvbmVudHMocGNhKSwKICAgICAgICB2bGluZSA9IGMoaG9ybiwgZWxib3cpLAogICAgICAgIHZsaW5lV2lkdGggPSAwLjI1LAogICAgICAgIHNpemVDdW11bGF0aXZlU3VtTGluZSA9IDAuNSwKICAgICAgICBzaXplQ3VtdWxhdGl2ZVN1bVBvaW50cyA9IDEuNQogICAgKSArCiAgICAgICAgZ2VvbV90ZXh0KGFlcyhob3JuICsgMSwgNTAsIGxhYmVsID0gIkhvcm4ncyIsIHZqdXN0ID0gMikpICsKICAgICAgICBnZW9tX3RleHQoYWVzKGVsYm93ICsgMSwgNTAsIGxhYmVsID0gIkVsYm93Iiwgdmp1c3QgPSAtMikpICsKICAgICAgICB0aGVtZV9zbGljayArCiAgICAgICAgZ2dwbG90Mjo6dGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxKSkKCiAgICByZXR1cm4oc2NyZWUpCn0KI1RPRE8gTm90ZSB3aGVyZSB0aGlzIGZ1bmN0aW9uIGlzIGJlaW5nIHVzZWQKI1RPRE8gQWRkIHJldHVybiBkZXNjcmlwdGlvbgoKCiMgIFNldCB1cCBjdXN0b20gZ2dwbG90MiBwbG90IHRoZW1lcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KdGhlbWVfc2xpY2sgPC0gdGhlbWVfY2xhc3NpYygpICsKICAgIHRoZW1lKAogICAgICAgIHBhbmVsLmdyaWQubWFqb3IgPSBnZ3Bsb3QyOjplbGVtZW50X2xpbmUobGluZXdpZHRoID0gMC40KSwKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZ2dwbG90Mjo6ZWxlbWVudF9saW5lKGxpbmV3aWR0aCA9IDAuMiksCiAgICAgICAgYXhpcy5saW5lID0gZ2dwbG90Mjo6ZWxlbWVudF9saW5lKGxpbmV3aWR0aCA9IDAuMiksCiAgICAgICAgYXhpcy50aWNrcyA9IGdncGxvdDI6OmVsZW1lbnRfbGluZShsaW5ld2lkdGggPSAwLjQpLAogICAgICAgIGF4aXMudGV4dCA9IGdncGxvdDI6OmVsZW1lbnRfdGV4dChjb2xvciA9ICJibGFjayIpLAogICAgICAgIGF4aXMudGl0bGUueCA9IGdncGxvdDI6OmVsZW1lbnRfdGV4dCgpLAogICAgICAgIGF4aXMudGl0bGUueSA9IGdncGxvdDI6OmVsZW1lbnRfdGV4dCgpLAogICAgICAgIHBsb3QudGl0bGUgPSBnZ3Bsb3QyOjplbGVtZW50X3RleHQoKSwKICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICIiKQogICAgKQojVE9ETyBOb3RlIHdoZXJlIHRoaXMgdGhlbWUgaXMgYmVpbmcgdXNlZAoKdGhlbWVfc2xpY2tfbm9fbGVnZW5kIDwtIHRoZW1lX3NsaWNrICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQojVE9ETyBOb3RlIHdoZXJlIHRoaXMgdGhlbWUgaXMgYmVpbmcgdXNlZApgYGAKPGJyIC8+CgojIyMgTG9hZCBpbiBFeGNlbCBzcHJlYWRzaGVldCBvZiBzYW1wbGVzIG5hbWVzIGFuZCB2YXJpYWJsZXMKVGhlIHNwcmVhZHNoZWV0IGluY2x1ZGVzIEFsaXNvbidzIG9yaWdpbmFsIHNhbXBsZSBuYW1lczsgd2UgY2FuIHVzZSB0aGlzCmluZm9ybWF0aW9uIHRvIGFzc29jaWF0ZSB0aGUgbmV3IHNhbXBsZSBuYW1lcywgd2hpY2ggYXJlIG1hZGUgdXAgb2YgYERFU2VxMmAKR0xNIHZhcmlhYmxlcywgd2l0aCB0aGUgb2xkIG5hbWVzLCB3aGljaCByZWZsZWN0IEFsaXNvbidzIHdldC1sYWIsCmxpYnJhcnktcHJlcCwgZXRjLiB3b3JrCmBgYHtyIExvYWQgc3ByZWFkc2hlZXQsIGVjaG89RkFMU0UsIHJlc3VsdHM9J2hpZGUnLCBtZXNzYWdlPUZBTFNFfQpwX3hsIDwtICJub3RlYm9vayIgICNJTlBBVEgKZl94bCA8LSAidmFyaWFibGVzLnhsc3giICAjSU5GSUxFCnRfeGwgPC0gcmVhZHhsOjpyZWFkX3hsc3goCiAgICBwYXN0ZShwX3hsLCBmX3hsLCBzZXAgPSAiLyIpLCBzaGVldCA9ICJtYXN0ZXIiLCBuYSA9ICJOQSIKKQoKcm0ocF94bCwgZl94bCkKYGBgCjxiciAvPgoKIyMjIExvYWQgaW4gYW5kIHByb2Nlc3MgYGZlYXR1cmVDb3VudHNgIHRhYmxlcwojIyMjIFByb2Nlc3MgdGhlIHNlbnNlIGBmZWF0dXJlQ291bnRzYCB0YWJsZQpgYGB7ciBQcm9jZXNzIHNlbnNlIGZlYXR1cmVDb3VudHMgdGFibGUsIGVjaG89RkFMU0UsIHJlc3VsdHM9J2hpZGUnLCBtZXNzYWdlPUZBTFNFfQojICBMb2FkIGluIGZlYXR1cmVDb3VudHMgdGFibGUgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnBfZmNfc2VuIDwtICJvdXRmaWxlc19mZWF0dXJlQ291bnRzL2NvbWJpbmVkX1NDX0tML1VUX3ByaW1fVU1JIiAgI0lOUEFUSApmX2ZjX3NlbiA8LSAiVVRfcHJpbV9VTUkuZmVhdHVyZUNvdW50cyIgICNJTkZJTEUKdF9mY19zZW4gPC0gcmVhZC50YWJsZSgKICAgIHBhc3RlKHBfZmNfc2VuLCBmX2ZjX3Nlbiwgc2VwID0gIi8iKSwgaGVhZGVyID0gVFJVRSwgcm93Lm5hbWVzID0gMQopICU+JSAKICAgIHRpYmJsZTo6cm93bmFtZXNfdG9fY29sdW1uKCkgJT4lCiAgICB0aWJibGU6OmFzX3RpYmJsZSgpCgpybShwX2ZjX3NlbiwgZl9mY19zZW4pCgoKIyAgQ2xlYW4gdXAgdGliYmxlIGNvbHVtbiBuYW1lcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpjb2xuYW1lcyh0X2ZjX3NlbikgPC0gY29sbmFtZXModF9mY19zZW4pICU+JQogICAgZ3N1Yigicm93bmFtZSIsICJmZWF0dXJlX2luaXQiLCAuKSAlPiUKICAgIGdzdWIoIkNociIsICJjaHIiLCAuKSAlPiUKICAgIGdzdWIoIlN0YXJ0IiwgInN0YXJ0IiwgLikgJT4lCiAgICBnc3ViKCJFbmQiLCAiZW5kIiwgLikgJT4lCiAgICBnc3ViKCJTdHJhbmQiLCAic3RyYW5kIiwgLikgJT4lCiAgICBnc3ViKCJMZW5ndGgiLCAibGVuZ3RoIiwgLikgJT4lCiAgICBnc3ViKCJiYW1zX3JlbmFtZWRcXC5VVF9wcmltX1VNSVxcLiIsICIiLCAuKSAlPiUKICAgIGdzdWIoIlxcLlVUX3ByaW1fVU1JXFwuYmFtIiwgIiIsIC4pICU+JQogICAgZ3N1YigiXFwuZCIsICItZCIsIC4pICU+JQogICAgZ3N1YigiXFwubiIsICItbiIsIC4pICU+JQogICAgZ3N1YigiYXV4XFwuIiwgImF1eC0iLCAuKSAlPiUKICAgIGdzdWIoInRjXFwuIiwgInRjLSIsIC4pCgoKIyAgT3JkZXIgdGliYmxlIGJ5IGNocm9tb3NvbWUgbmFtZXMgYW5kIGZlYXR1cmUgc3RhcnQgcG9zaXRpb25zIC0tLS0tLS0tLS0tLS0tLQpjaHJfU0MgPC0gYygKICAgICJJIiwgIklJIiwgIklJSSIsICJJViIsICJWIiwgIlZJIiwgIlZJSSIsICJWSUlJIiwgIklYIiwgIlgiLCAiWEkiLCAiWElJIiwKICAgICJYSUlJIiwgIlhJViIsICJYViIsICJYVkkiLCAiTWl0byIKKQpjaHJfS0wgPC0gYygiQSIsICJCIiwgIkMiLCAiRCIsICJFIiwgIkYiKQpjaHJfb3JkZXIgPC0gYyhjaHJfU0MsIGNocl9LTCkKdF9mY19zZW4kY2hyIDwtIHRfZmNfc2VuJGNociAlPiUgYXMuZmFjdG9yKCkKdF9mY19zZW4kY2hyIDwtIG9yZGVyZWQodF9mY19zZW4kY2hyLCBsZXZlbHMgPSBjaHJfb3JkZXIpCgp0X2ZjX3NlbiA8LSB0X2ZjX3NlbiAlPiUgZHBseXI6OmFycmFuZ2UoY2hyLCBzdGFydCkKCgojICBDYXRlZ29yaXplIGNocm9tb3NvbWVzIGJ5IGdlbm9tZSBvZiBvcmlnaW4gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnRfZmNfc2VuJGdlbm9tZSA8LSBpZmVsc2UoCiAgICB0X2ZjX3NlbiRjaHIgJWluJSBjaHJfU0MsCiAgICAiU19jZXJldmlzaWFlIiwKICAgIGlmZWxzZSgKICAgICAgICB0X2ZjX3NlbiRjaHIgJWluJSBjaHJfS0wsCiAgICAgICAgIktfbGFjdGlzIiwKICAgICAgICBOQQogICAgKQopICU+JQogICAgYXMuZmFjdG9yKCkKCiMgIE1vdmUgdGhlIG5ldyBjb2x1bW4gImdlbm9tZSIgdG8gYSBiZXR0ZXIgbG9jYXRpb24gaW4gdGhlIHRpYmJsZSAoYmVmb3JlCiMrIGNvbHVtbiAiY2hyIikKdF9mY19zZW4gPC0gdF9mY19zZW4gJT4lIGRwbHlyOjpyZWxvY2F0ZSgiZ2Vub21lIiwgLmJlZm9yZSA9ICJjaHIiKQoKIyAgQ2hlY2sgb24gdmFyaWFibGUvY29sdW1uICJnZW5vbWUiCmxldmVscyh0X2ZjX3NlbiRnZW5vbWUpCnRfZmNfc2VuICU+JQogICAgZHBseXI6Omdyb3VwX2J5KGdlbm9tZSkgJT4lCiAgICBkcGx5cjo6c3VtbWFyaXplKHRhbGx5ID0gbGVuZ3RoKGdlbm9tZSkpCiMgIFRoZSBjb2RlIHJldHVybnMuLi4KIyBLX2xhY3RpcyA9IDU2NTksIFNfY2VyZXZpc2lhZSA9IDc1MDcKCnJtKGNocl9LTCwgY2hyX1NDLCBjaHJfb3JkZXIpCgoKIyAgU3BsaXQgYW5kIGJldHRlciBvcmdhbml6ZSB2YXJpYWJsZSAnZmVhdHVyZV9pbml0JyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojICBTcGxpdCAnZmVhdHVyZV9pbml0JyBpbnRvIHR3byBkaXN0aW5jdCBlbGVtZW50cyAoc2VwYXJhdGVkIGJ5IGFuIHVuZGVyc2NvcmUpCmVsXzEgPC0gc3BsaXRfaXNvbGF0ZV9jb252ZXJ0KAogICAgaW5fdmVjdG9yID0gdF9mY19zZW4kZmVhdHVyZV9pbml0LAogICAgZmllbGQgPSAxLAogICAgY29sdW1uX25hbWUgPSAiZmVhdHVyZSIKKQplbF8yIDwtIHNwbGl0X2lzb2xhdGVfY29udmVydCgKICAgIGluX3ZlY3RvciA9IHRfZmNfc2VuJGZlYXR1cmVfaW5pdCwKICAgIGZpZWxkID0gMiwKICAgIGNvbHVtbl9uYW1lID0gInR5cGUiCikKCiMgIEFwcGVuZCBzcGxpdCBpbmZvcm1hdGlvbiB0byB0aWJibGUgJ3RfZmNfc2VuJwp0X2ZjX3NlbiA8LSBkcGx5cjo6YmluZF9jb2xzKHRfZmNfc2VuLCBlbF8xLCBlbF8yKSAlPiUKICAgIGRwbHlyOjpyZWxvY2F0ZShjKCJmZWF0dXJlIiwgInR5cGUiKSwgLmFmdGVyID0gImZlYXR1cmVfaW5pdCIpCgpybShlbF8xLCBlbF8yKQoKIyAgTGltaXQgdGhlIHNwbGl0dGluZy9yZW9yZ2FuaXphdGlvbiB0byBTLiBjZXJldmlzaWFlIGZlYXR1cmVzIG9ubHk7IHRoZSBhYm92ZQojKyBzcGxpdHRpbmcvcmVvcmdhbml6YXRpb24gd29yayBpc24ndCBhcHByb3ByaWF0ZSBmb3IgSy4gbGFjdGlzICdmZWF0dXJlX2luaXQnCiMrIGluZm9ybWF0aW9uIGJlY2F1c2UgdGhlIEsuIGxhY3RpcyBuYW1pbmcvY2xhc3NpZmljYXRpb24gZGlmZmVycyBmcm9tIHRoZSBTLgojKyBjZXJldmlzaWFlIG5hbWluZy9jbGFzc2lmaWNhdGlvbiBzeXN0ZW0pCnRfZmNfc2VuJGZlYXR1cmUgPC0gaWZlbHNlKAogICAgdF9mY19zZW4kZ2Vub21lID09ICJLX2xhY3RpcyIsIHRfZmNfc2VuJGZlYXR1cmVfaW5pdCwgdF9mY19zZW4kZmVhdHVyZQopCnRfZmNfc2VuJHR5cGUgPC0gaWZlbHNlKAogICAgdF9mY19zZW4kZ2Vub21lID09ICJLX2xhY3RpcyIsIE5BLCB0X2ZjX3NlbiR0eXBlCikKCiMgIENyZWF0ZSBsZXZlbHMgZm9yIFMuIGNlcmV2aXNpYWUgJ3R5cGUnIE5BcyBhbmQgSy4gbGFjdGlzICd0eXBlJyBOQXMsIHRoZW4KIysgZmFjdG9yaXplIHZhcmlhYmxlICd0eXBlJzogZXNzZW50aWFsbHksIHdlJ3JlIG1ha2luZyB0aGUgTkFzIGludG8gbGV2ZWxzIHNvCiMrIHRoYXQgd2UgY2FuIHRhbGx5IHRoZW0gKGFzIGJlbG93KSBhbmQvb3IgcG90ZW50aWFsbHkgc3Vic2V0IHRoZW07IGhvd2V2ZXIsCiMrIGJlZm9yZSBkb2luZyBzbywgd2UncmUgZGlmZmVyZW50aWF0aW5nIHRoZSBOQXMgYnkgd2hldGhlciB0aGV5IGFyZQojKyBhc3NvY2lhdGVkIHdpdGggUy4gY2VyZXZpc2lhZSBmZWF0dXJlcyBvciBLLiBsYWN0aXMgZmVhdHVyZXMKdF9mY19zZW4kdHlwZSA8LSAgaWZlbHNlKAogICAgKHRfZmNfc2VuJGdlbm9tZSA9PSAiU19jZXJldmlzaWFlIiAmIGlzLm5hKHRfZmNfc2VuJHR5cGUpKSwKICAgICJOQV9TQyIsCiAgICBpZmVsc2UoCiAgICAgICAgKHRfZmNfc2VuJGdlbm9tZSA9PSAiS19sYWN0aXMiICYgaXMubmEodF9mY19zZW4kdHlwZSkpLAogICAgICAgICJOQV9LTCIsCiAgICAgICAgdF9mY19zZW4kdHlwZQogICAgKQopICU+JQogICAgYXMuZmFjdG9yKCkKCiMgIERvIGEgcXVpY2sgY2hlY2sgb2YgdGhlIHRpYmJsZSAndF9mY19zZW4nICh3aGVyZSAidF9mY19zZW4iIHN0YW5kcyBmb3IgInRpYmJsZQojKyBmZWF0dXJlQ291bnRzIikKdF9mY19zZW4KCiMgIENoZWNrIG9uIHRoZSBzcGxpdCBpbmZvcm1hdGlvbjogVGhpcyBjb2RlIHRhbGxpZXMgdGhlIG51bWJlcnMgb2YgZmVhdHVyZXMKIysgcGVyIGNsYXNzaWZpY2F0aW9uLCB3aGVyZSBjbGFzc2lmaWNhdGlvbnMgYXJlIHRoaW5ncyBsaWtlICJtUk5BLUUxIiwKIysgInRSTkEtRTEiLCAiTkFfU0MiIChOQXMgYXNzb2NpYXRlZCB3aXRoIFMuIGNlcmV2aXNpYWUpLCAiTkFfS0wiIChOQXMgYXNzb2NpLQojKyBhdGVkIHdpdGggSy4gbGFjdGlzKSwgZXRjLgpsZXZlbHModF9mY19zZW4kdHlwZSkgICMgMTkgbGV2ZWxzCnRfZmNfc2VuICU+JQogICAgZHBseXI6Omdyb3VwX2J5KHR5cGUpICU+JQogICAgZHBseXI6OnN1bW1hcml6ZSh0YWxseSA9IGxlbmd0aCh0eXBlKSkKIyAgVGhlIGNvZGUgcmV0dXJucyB0aGluZ3MgbGlrZS4uLgojKyBtUk5BLUUxID0gNjYwMCwgbVJOQS1FMiA9IDI4MywgTkFfS0wgPSA1NTQ3LCBOQV9TQyA9IDEwMywgdFJOQS1FMSA9IDI5OSwKIysgdFJOQS1FMiA9IDYwLCBldGMuCmBgYAo8YnIgLz4KCiMjIyMgUHJvY2VzcyB0aGUgYW50aXNlbnNlIGBmZWF0dXJlQ291bnRzYCB0YWJsZQpgYGB7ciBQcm9jZXNzIGFudGlzZW5zZSBmZWF0dXJlQ291bnRzIHRhYmxlLCBlY2hvPUZBTFNFLCByZXN1bHRzPSdoaWRlJywgbWVzc2FnZT1GQUxTRX0KIyAgTG9hZCBpbiBmZWF0dXJlQ291bnRzIHRhYmxlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpwX2ZjX2FudGkgPC0gIm91dGZpbGVzX2ZlYXR1cmVDb3VudHMvY29tYmluZWRfU0NfS0xfYW50aXNlbnNlL1VUX3ByaW1fVU1JIiAgI0lOUEFUSApmX2ZjX2FudGkgPC0gIlVUX3ByaW1fVU1JLmZlYXR1cmVDb3VudHMiICAjSU5GSUxFCnRfZmNfYW50aSA8LSByZWFkLnRhYmxlKAogICAgcGFzdGUocF9mY19hbnRpLCBmX2ZjX2FudGksIHNlcCA9ICIvIiksIGhlYWRlciA9IFRSVUUsIHJvdy5uYW1lcyA9IDEKKSAlPiUgCiAgICB0aWJibGU6OnJvd25hbWVzX3RvX2NvbHVtbigpICU+JQogICAgdGliYmxlOjphc190aWJibGUoKQoKcm0ocF9mY19hbnRpLCBmX2ZjX2FudGkpCgoKIyAgQ2xlYW4gdXAgdGliYmxlIGNvbHVtbiBuYW1lcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpjb2xuYW1lcyh0X2ZjX2FudGkpIDwtIGNvbG5hbWVzKHRfZmNfYW50aSkgJT4lCiAgICBnc3ViKCJyb3duYW1lIiwgImZlYXR1cmVfaW5pdCIsIC4pICU+JQogICAgZ3N1YigiQ2hyIiwgImNociIsIC4pICU+JQogICAgZ3N1YigiU3RhcnQiLCAic3RhcnQiLCAuKSAlPiUKICAgIGdzdWIoIkVuZCIsICJlbmQiLCAuKSAlPiUKICAgIGdzdWIoIlN0cmFuZCIsICJzdHJhbmQiLCAuKSAlPiUKICAgIGdzdWIoIkxlbmd0aCIsICJsZW5ndGgiLCAuKSAlPiUKICAgIGdzdWIoImJhbXNfcmVuYW1lZFxcLlVUX3ByaW1fVU1JXFwuIiwgIiIsIC4pICU+JQogICAgZ3N1YigiXFwuVVRfcHJpbV9VTUlcXC5iYW0iLCAiIiwgLikgJT4lCiAgICBnc3ViKCJcXC5kIiwgIi1kIiwgLikgJT4lCiAgICBnc3ViKCJcXC5uIiwgIi1uIiwgLikgJT4lCiAgICBnc3ViKCJhdXhcXC4iLCAiYXV4LSIsIC4pICU+JQogICAgZ3N1YigidGNcXC4iLCAidGMtIiwgLikKCgojICBPcmRlciB0aWJibGUgYnkgY2hyb21vc29tZSBuYW1lcyBhbmQgZmVhdHVyZSBzdGFydCBwb3NpdGlvbnMgLS0tLS0tLS0tLS0tLS0tCmNocl9TQyA8LSBjKAogICAgIkkiLCAiSUkiLCAiSUlJIiwgIklWIiwgIlYiLCAiVkkiLCAiVklJIiwgIlZJSUkiLCAiSVgiLCAiWCIsICJYSSIsICJYSUkiLAogICAgIlhJSUkiLCAiWElWIiwgIlhWIiwgIlhWSSIsICJNaXRvIgopCmNocl9LTCA8LSBjKCJBIiwgIkIiLCAiQyIsICJEIiwgIkUiLCAiRiIpCmNocl9vcmRlciA8LSBjKGNocl9TQywgY2hyX0tMKQp0X2ZjX2FudGkkY2hyIDwtIHRfZmNfYW50aSRjaHIgJT4lIGFzLmZhY3RvcigpCnRfZmNfYW50aSRjaHIgPC0gb3JkZXJlZCh0X2ZjX2FudGkkY2hyLCBsZXZlbHMgPSBjaHJfb3JkZXIpCgp0X2ZjX2FudGkgPC0gdF9mY19hbnRpICU+JSBkcGx5cjo6YXJyYW5nZShjaHIsIHN0YXJ0KQoKCiMgIENhdGVnb3JpemUgY2hyb21vc29tZXMgYnkgZ2Vub21lIG9mIG9yaWdpbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KdF9mY19hbnRpJGdlbm9tZSA8LSBpZmVsc2UoCiAgICB0X2ZjX2FudGkkY2hyICVpbiUgY2hyX1NDLAogICAgIlNfY2VyZXZpc2lhZSIsCiAgICBpZmVsc2UoCiAgICAgICAgdF9mY19hbnRpJGNociAlaW4lIGNocl9LTCwKICAgICAgICAiS19sYWN0aXMiLAogICAgICAgIE5BCiAgICApCikgJT4lCiAgICBhcy5mYWN0b3IoKQoKIyAgTW92ZSB0aGUgbmV3IGNvbHVtbiAiZ2Vub21lIiB0byBhIGJldHRlciBsb2NhdGlvbiBpbiB0aGUgdGliYmxlIChiZWZvcmUKIysgY29sdW1uICJjaHIiKQp0X2ZjX2FudGkgPC0gdF9mY19hbnRpICU+JSBkcGx5cjo6cmVsb2NhdGUoImdlbm9tZSIsIC5iZWZvcmUgPSAiY2hyIikKCiMgIENoZWNrIG9uIHZhcmlhYmxlL2NvbHVtbiAiZ2Vub21lIgpsZXZlbHModF9mY19hbnRpJGdlbm9tZSkKdF9mY19hbnRpICU+JQogICAgZHBseXI6Omdyb3VwX2J5KGdlbm9tZSkgJT4lCiAgICBkcGx5cjo6c3VtbWFyaXplKHRhbGx5ID0gbGVuZ3RoKGdlbm9tZSkpCiMgIFRoZSBjb2RlIHJldHVybnMuLi4KIyBLX2xhY3RpcyA9IDU2NTksIFNfY2VyZXZpc2lhZSA9IDc1MDcKCnJtKGNocl9LTCwgY2hyX1NDLCBjaHJfb3JkZXIpCgoKIyAgU3BsaXQgYW5kIGJldHRlciBvcmdhbml6ZSB2YXJpYWJsZSAnZmVhdHVyZV9pbml0JyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojICBTcGxpdCAnZmVhdHVyZV9pbml0JyBpbnRvIHR3byBkaXN0aW5jdCBlbGVtZW50cyAoc2VwYXJhdGVkIGJ5IGFuIHVuZGVyc2NvcmUpCmVsXzEgPC0gc3BsaXRfaXNvbGF0ZV9jb252ZXJ0KAogICAgaW5fdmVjdG9yID0gdF9mY19hbnRpJGZlYXR1cmVfaW5pdCwKICAgIGZpZWxkID0gMSwKICAgIGNvbHVtbl9uYW1lID0gImZlYXR1cmUiCikKZWxfMiA8LSBzcGxpdF9pc29sYXRlX2NvbnZlcnQoCiAgICBpbl92ZWN0b3IgPSB0X2ZjX2FudGkkZmVhdHVyZV9pbml0LAogICAgZmllbGQgPSAyLAogICAgY29sdW1uX25hbWUgPSAidHlwZSIKKQoKIyAgQXBwZW5kIHNwbGl0IGluZm9ybWF0aW9uIHRvIHRpYmJsZSAndF9mY19hbnRpJwp0X2ZjX2FudGkgPC0gZHBseXI6OmJpbmRfY29scyh0X2ZjX2FudGksIGVsXzEsIGVsXzIpICU+JQogICAgZHBseXI6OnJlbG9jYXRlKGMoImZlYXR1cmUiLCAidHlwZSIpLCAuYWZ0ZXIgPSAiZmVhdHVyZV9pbml0IikKCnJtKGVsXzEsIGVsXzIpCgojICBMaW1pdCB0aGUgc3BsaXR0aW5nL3Jlb3JnYW5pemF0aW9uIHRvIFMuIGNlcmV2aXNpYWUgZmVhdHVyZXMgb25seTsgdGhlIGFib3ZlCiMrIHNwbGl0dGluZy9yZW9yZ2FuaXphdGlvbiB3b3JrIGlzbid0IGFwcHJvcHJpYXRlIGZvciBLLiBsYWN0aXMgJ2ZlYXR1cmVfaW5pdCcKIysgaW5mb3JtYXRpb24gYmVjYXVzZSB0aGUgSy4gbGFjdGlzIG5hbWluZy9jbGFzc2lmaWNhdGlvbiBkaWZmZXJzIGZyb20gdGhlIFMuCiMrIGNlcmV2aXNpYWUgbmFtaW5nL2NsYXNzaWZpY2F0aW9uIHN5c3RlbSkKdF9mY19hbnRpJGZlYXR1cmUgPC0gaWZlbHNlKAogICAgdF9mY19hbnRpJGdlbm9tZSA9PSAiS19sYWN0aXMiLCB0X2ZjX2FudGkkZmVhdHVyZV9pbml0LCB0X2ZjX2FudGkkZmVhdHVyZQopCnRfZmNfYW50aSR0eXBlIDwtIGlmZWxzZSgKICAgIHRfZmNfYW50aSRnZW5vbWUgPT0gIktfbGFjdGlzIiwgTkEsIHRfZmNfYW50aSR0eXBlCikKCiMgIENyZWF0ZSBsZXZlbHMgZm9yIFMuIGNlcmV2aXNpYWUgJ3R5cGUnIE5BcyBhbmQgSy4gbGFjdGlzICd0eXBlJyBOQXMsIHRoZW4KIysgZmFjdG9yaXplIHZhcmlhYmxlICd0eXBlJzogZXNzZW50aWFsbHksIHdlJ3JlIG1ha2luZyB0aGUgTkFzIGludG8gbGV2ZWxzIHNvCiMrIHRoYXQgd2UgY2FuIHRhbGx5IHRoZW0gKGFzIGJlbG93KSBhbmQvb3IgcG90ZW50aWFsbHkgc3Vic2V0IHRoZW07IGhvd2V2ZXIsCiMrIGJlZm9yZSBkb2luZyBzbywgd2UncmUgZGlmZmVyZW50aWF0aW5nIHRoZSBOQXMgYnkgd2hldGhlciB0aGV5IGFyZQojKyBhc3NvY2lhdGVkIHdpdGggUy4gY2VyZXZpc2lhZSBmZWF0dXJlcyBvciBLLiBsYWN0aXMgZmVhdHVyZXMKdF9mY19hbnRpJHR5cGUgPC0gIGlmZWxzZSgKICAgICh0X2ZjX2FudGkkZ2Vub21lID09ICJTX2NlcmV2aXNpYWUiICYgaXMubmEodF9mY19hbnRpJHR5cGUpKSwKICAgICJOQV9TQyIsCiAgICBpZmVsc2UoCiAgICAgICAgKHRfZmNfYW50aSRnZW5vbWUgPT0gIktfbGFjdGlzIiAmIGlzLm5hKHRfZmNfYW50aSR0eXBlKSksCiAgICAgICAgIk5BX0tMIiwKICAgICAgICB0X2ZjX2FudGkkdHlwZQogICAgKQopICU+JQogICAgYXMuZmFjdG9yKCkKCiMgIERvIGEgcXVpY2sgY2hlY2sgb2YgdGhlIHRpYmJsZSAndF9mY19hbnRpJyAod2hlcmUgInRfZmNfYW50aSIgc3RhbmRzIGZvciAidGliYmxlCiMrIGZlYXR1cmVDb3VudHMiKQp0X2ZjX2FudGkKCiMgIENoZWNrIG9uIHRoZSBzcGxpdCBpbmZvcm1hdGlvbjogVGhpcyBjb2RlIHRhbGxpZXMgdGhlIG51bWJlcnMgb2YgZmVhdHVyZXMKIysgcGVyIGNsYXNzaWZpY2F0aW9uLCB3aGVyZSBjbGFzc2lmaWNhdGlvbnMgYXJlIHRoaW5ncyBsaWtlICJtUk5BLUUxIiwKIysgInRSTkEtRTEiLCAiTkFfU0MiIChOQXMgYXNzb2NpYXRlZCB3aXRoIFMuIGNlcmV2aXNpYWUpLCAiTkFfS0wiIChOQXMgYXNzb2NpLQojKyBhdGVkIHdpdGggSy4gbGFjdGlzKSwgZXRjLgpsZXZlbHModF9mY19hbnRpJHR5cGUpICAjIDE5IGxldmVscwp0X2ZjX2FudGkgJT4lCiAgICBkcGx5cjo6Z3JvdXBfYnkodHlwZSkgJT4lCiAgICBkcGx5cjo6c3VtbWFyaXplKHRhbGx5ID0gbGVuZ3RoKHR5cGUpKQojICBUaGUgY29kZSByZXR1cm5zIHRoaW5ncyBsaWtlLi4uCiMrIG1STkEtRTEgPSA2NjAwLCBtUk5BLUUyID0gMjgzLCBOQV9LTCA9IDU1NDcsIE5BX1NDID0gMTAzLCB0Uk5BLUUxID0gMjk5LAojKyB0Uk5BLUUyID0gNjAsIGV0Yy4KYGBgCjxiciAvPgoKIyMjIENyZWF0ZSB0aWJibGU6IEFudGlzZW5zZSAqUy4gY2VyZXZpc2lhZSogY291bnRzLCBzZW5zZSAqSy4gbGFjdGlzKiBjb3VudHMKYGBge3IgQ3JlYXRlIHRpYmJsZSBvZiBhbnRpIFNDIGFuZCBzZW4gS0wsIGVjaG89RkFMU0UsIHJlc3VsdHM9J2hpZGUnLCBtZXNzYWdlPUZBTFNFfQp0X2ZjIDwtIGRwbHlyOjpiaW5kX3Jvd3MoCiAgICB0X2ZjX2FudGlbdF9mY19hbnRpJGdlbm9tZSA9PSAiU19jZXJldmlzaWFlIiwgXSwKICAgIHRfZmNfc2VuW3RfZmNfc2VuJGdlbm9tZSA9PSAiS19sYWN0aXMiLCBdCikKYGBgCgoKIyMjIFJlY29yZCB0aWJibGUgYHRfZmNgJ3MgcG9zaXRpb25hbCBpbmZvcm1hdGlvbiBpbiBhIGBHUmFuZ2VzYCBvYmplY3QKYHBvc19pbmZvYCB3aWxsIGJlIHVzZWQgaW4gYERFU2VxMmAgcHJvY2Vzc2luZywgcG9zdC1wcm9jZXNzaW5nLCBldGMuCgpgYGB7ciBSZWNvcmQgcG9zaXRpb25hbCBpbmZvcm1hdGlvbiwgZWNobz1GQUxTRSwgcmVzdWx0cz0naGlkZScsIG1lc3NhZ2U9RkFMU0V9CnBvc19pbmZvIDwtIEdlbm9taWNSYW5nZXM6OkdSYW5nZXMoCiAgICBzZXFuYW1lcyA9IHRfZmMkY2hyLAogICAgcmFuZ2VzID0gSVJhbmdlczo6SVJhbmdlcyh0X2ZjJHN0YXJ0LCB0X2ZjJGVuZCksCiAgICBzdHJhbmQgPSB0X2ZjJHN0cmFuZCwKICAgIGxlbmd0aCA9IHRfZmMkbGVuZ3RoLAogICAgZmVhdHVyZSA9IHRfZmMkZmVhdHVyZSwKICAgIGZlYXR1cmVfaW5pdCA9IHRfZmMkZmVhdHVyZV9pbml0LAogICAgdHlwZSA9IHRfZmMkdHlwZSwKICAgIGdlbm9tZSA9IHRfZmMkZ2Vub21lCikKcG9zX2luZm8KYGBgCjxiciAvPgo8YnIgLz4KCiMjIFBlcmZvcm0gbm9ybWFsaXphdGlvbiBhbmQgcnVuIERHRSBhbmFseXNlcwojIyMgUGVyZm9ybSBwcmVwIHdvcmsKIyMjIyBFc3RhYmxpc2ggdGFibGUgb2YgdmFyaWFibGVzIGZvciBgZGRzYCZtZGFzaDtpLmUuLCBhICJtYXN0ZXIiIG1vZGVsIG1hdHJpeAotIGBkZHNgIHN0YW5kcyBmb3IgKiJERVNlcTIgZGF0YXNldCIqIGFuZCBpcyBhIGBERVNlcURhdGFTZXRgIG9iamVjdAotIHZhcmlhYmxlcyBmb3IgYGRkc2AgYXJlCiAgICArIGBzdHJhaW5gCiAgICArIGBzdGF0ZWAKICAgICsgYHRpbWVgCiAgICArIGBraXRgICooYHRjbmAgZm9yICJUZWNhbiIsIGBvdm5gIGZvciAiT3ZhdGlvbiIpKgogICAgKyBgdHJhbnNjcmlwdGlvbmAgKihgTmAgZm9yICJuYXNjZW50IiwgYFNTYCBmb3IgInN0ZWFkeSBzdGF0ZSIpKgogICAgKyBgYXV4aW5gCiAgICArIGB0aW1lY291cnNlYAogICAgKyBgcmVwbGljYXRlYAogICAgKyBgdGVjaG5pY2FsYAoKYGBge3IgTWFrZSBhIG1hc3RlciBtb2RlbCBtYXRyaXgsIGVjaG89RkFMU0UsIHJlc3VsdHM9J2hpZGUnLCBtZXNzYWdlPUZBTFNFfQojICBDb2x1bW5zIDEwIHRocm91Z2ggdG8gdGhlIGxhc3QgY29sdW1uIGFyZSBjb21wb3NlZCBvZiBzYW1wbGUgZmVhdHVyZSBjb3VudHM7CiMrIGdldCB0aGVzZSBjb2x1bW4gbmFtZXMgaW50byBhIHZlY3RvcgpzYW1wbGVzIDwtIGNvbG5hbWVzKHRfZmMpWzEwOmxlbmd0aChjb2xuYW1lcyh0X2ZjKSldCgojICBDb252ZXJ0IHRoZSB2ZWN0b3Igb2YgY29sdW1uIG5hbWVzIHRvIGEgbGlzdCBieSBzcGxpdHRpbmcgZWFjaCBlbGVtZW50IGF0CiMrIGl0cyB1bmRlcnNjb3JlczsgdGh1cywgZWFjaCB2ZWN0b3IgZWxlbWVudCBiZWNvbWVzIGEgbGlzdCBvZiBlaWdodCBzdHJpbmdzLAojKyB3aXRoIG9uZSBzdHJpbmcgZm9yICdzdHJhaW4nLCBvbmUgZm9yICdzdGF0ZScsIGV0Yy47IHRoZXNlIApzYW1wbGVzIDwtIHN0cmluZ3I6OnN0cl9zcGxpdChzYW1wbGVzLCAiXyIpCgojICBDb252ZXJ0IHRoZSBsaXN0IHRvIGEgZGF0YWZyYW1lLCB0cmFuc3Bvc2UgaXQsIHRoZW4gY29udmVydCBpdCB0byBhIHRpYmJsZQojKyBbUiBmdW4gZmFjdDogJ3RpYmJsZScgZGF0YSB0eXBlcyBjYW4ndCBiZSBidWlsdCBkaXJlY3RseSBmcm9tICdsaXN0JyBkYXRhCiMrIHR5cGVzOyBpbiBmYWN0LCBpdCBjYW4gZGlmZmljdWx0IHRvIGJ1aWxkICdkYXRhZnJhbWUnIHR5cGVzIGZyb20gJ2xpc3QnCiMrIHR5cGVzIGFzIHdlbGw7IHRoZSByZWFzb24gd2UgaGF2ZSBubyBpc3N1ZXMgZG9pbmcgdGhpcyBpcyBiZWNhdXNlIHdlIGhhdmUKIysgZW5zdXJlZCBhaGVhZCBvZiB0aW1lIHRoYXQgZWFjaCBsaXN0IGVsZW1lbnQgaGFzIHRoZSBzYW1lIG51bWJlciBvZgojKyBzdWJlbGVtZW50cyAoOCk7IHRoZSBkaWZmaWN1bHR5IGFyaXNlcyB3aGVuIGxpc3RzIGVsZW1lbnRzIGhhdmUgdmFyeWluZwojKyBudW1iZXJzIG9mIHN1YmVsZW1lbnRzXQpzYW1wbGVzIDwtIHNhbXBsZXMgJT4lCiAgICBhcy5kYXRhLmZyYW1lKAogICAgICAgIC4sCiAgICAgICAgIyAgVXNpbmcgbnVtZXJpYyBjb2x1bW4gbmFtZXMgaGVyZSBiZWNhdXNlIHRoZSBjb2x1bW5zIHdpbGwgc29vbiBiZQogICAgICAgICMrIHRyYW5zcG9zZWQgdG8gcm93cywgYW5kIEkgZG9uJ3Qgd2FudCB0aGUgcm93cyB0byBoYXZlIHByb3BlciBuYW1lcwogICAgICAgIGNvbC5uYW1lcyA9IGMoc2VxKDEsIDYyKSksCiAgICAgICAgIyAgVXNpbmcgcHJvcGVyIHJvdyBuYW1lcyBoZXJlIGJlY2F1c2UgdGhlIHJvd3Mgd2lsbCBzb29uIGJlIHRyYW5zcG9zZWQKICAgICAgICAjKyB0byBjb2x1bW5zLCBhbmQgSSAqZG8qIHdhbnQgdGhlIGNvbHVtbnMgdG8gaGF2ZSBwcm9wZXIgbmFtZXMgCiAgICAgICAgcm93Lm5hbWVzID0gYygKICAgICAgICAgICAgInN0cmFpbiIsICJzdGF0ZSIsICJ0aW1lIiwgImtpdCIsICJ0cmFuc2NyaXB0aW9uIiwgImF1eGluIiwKICAgICAgICAgICAgInRpbWVjb3Vyc2UiLCAicmVwbGljYXRlIiwgInRlY2huaWNhbCIKICAgICAgICApCiAgICApICU+JQogICAgdCgpICU+JQogICAgdGliYmxlOjphc190aWJibGUoKQoKIyAgQWRkIGEga2V5cyB2YXJpYWJsZSBmb3IgcXVpY2tseSBhY2Nlc3NpbmcgY29tYmluYXRpb25zIG9mIHZhcmlhYmxlIHZhbHVlcwprZXlzIDwtIHZlY3Rvcihtb2RlID0gImNoYXJhY3RlciIpCmZvcihpIGluIHNlcSgxLCBucm93KHNhbXBsZXMpKSkgewogICAgIyBpIDwtIDEKICAgIGtleXNbaV0gPC0gcGFzdGUoCiAgICAgICAgc2FtcGxlc1tpLCAxXSwgc2FtcGxlc1tpLCAyXSwgc2FtcGxlc1tpLCAzXSwKICAgICAgICBzYW1wbGVzW2ksIDRdLCBzYW1wbGVzW2ksIDVdLCBzYW1wbGVzW2ksIDZdLAogICAgICAgIHNhbXBsZXNbaSwgN10sIHNhbXBsZXNbaSwgOF0sIHNhbXBsZXNbaSwgOV0sCiAgICAgICAgc2VwID0gIl8iCiAgICApCn0Ka2V5cyA8LSBrZXlzICU+JSBhcy5kYXRhLmZyYW1lKCkKY29sbmFtZXMoa2V5cykgPC0gImtleXMiCgpzYW1wbGVzIDwtIGRwbHlyOjpiaW5kX2NvbHMoc2FtcGxlcywga2V5cykgJT4lCiAgICBkcGx5cjo6cmVsb2NhdGUoImtleXMiLCAuYmVmb3JlID0gInN0cmFpbiIpCgpybShpKQoKIyAgQWRkIEFsaXNvbidzIG9yaWdpbmFsIHNhbXBsZXMgbmFtZXMgdG8gdGhlICdzYW1wbGVzJyBkYXRhZnJhbWUgdXNpbmcgdGhlCiMrICd0X3hsJyBkYXRhZnJhbWU7IGhlcmUsIHdlJ3JlIGp1c3QgYWRkaW5nIHRoZSBvcmlnaW5hbCBzYW1wbGUgbmFtZXMsIGJ1dCB3ZQojKyBjb3VsZCBwb3RlbnRpYWxseSBhZGQgaW4gb3RoZXIgaW5mb3JtYXRpb24gc3RvcmVkIGluIHRoZSBFeGNlbCBmaWxlCnRfeGwgPC0gdF94bCAlPiUKICAgIGRwbHlyOjpyZW5hbWUoa2V5cyA9IG5hbWUpICU+JQogICAgZHBseXI6OnNlbGVjdCguLCBjKGtleXMsIHNhbXBsZV9uYW1lKSkKc2FtcGxlcyA8LSBkcGx5cjo6ZnVsbF9qb2luKHNhbXBsZXMsIHRfeGwsIGJ5ID0gImtleXMiKQoKIyAgQ29udmVydCBhbGwgY29sdW1ucyB0byBkYXRhIHR5cGUgJ2ZhY3RvcicgKGhhdmluZyB0aGUgdmFyaWFibGUgdmFsdWVzIGFzCiMrIGZhY3RvcnMgaGVscHMgd2l0aCBydW5uaW5nIERFU2VxMjo6REVTZXFEYXRhU2V0RnJvbU1hdHJpeCgpIGJlbG93KQpzYW1wbGVzW3NhcHBseShzYW1wbGVzLCBpcy5jaGFyYWN0ZXIpXSA8LSBsYXBwbHkoCiAgICBzYW1wbGVzW3NhcHBseShzYW1wbGVzLCBpcy5jaGFyYWN0ZXIpXSwgYXMuZmFjdG9yCikKCiMgIEhvdyBkb2VzIGl0IGxvb2s/CnNhbXBsZXMKCnJtKHRfeGwsIGtleXMpCmBgYAo8YnIgLz4KPGJyIC8+CgojIyBEbyBwcmVwIHdvcmsgZm9yIHJ1bm5pbmcgYERFU2VxMmAKIyMjIE1ha2UgdGhlIGNvdW50cyBtYXRyaXgKYGBge3IgTWFrZSB0aGUgY291bnRzIG1hdHJpeCwgZWNobz1GQUxTRSwgcmVzdWx0cz0naGlkZScsIG1lc3NhZ2U9RkFMU0V9CmRhdGFzZXRzIDwtIGMoCiAgICAibjMtZF9RX2RheTdfdGNuX05fYXV4LVRfdGMtRl9yZXAxX3RlY2gxIiwKICAgICJuMy1kX1FfZGF5N190Y25fTl9hdXgtVF90Yy1GX3JlcDJfdGVjaDEiLAogICAgIm4zLWRfUV9kYXk3X3Rjbl9OX2F1eC1UX3RjLUZfcmVwM190ZWNoMSIsCiAgICAiby1kX1FfZGF5N190Y25fTl9hdXgtVF90Yy1GX3JlcDFfdGVjaDEiLAogICAgIm8tZF9RX2RheTdfdGNuX05fYXV4LVRfdGMtRl9yZXAyX3RlY2gxIgopCmNvdW50c19kYXRhIDwtIHRfZmNbLCBjb2xuYW1lcyh0X2ZjKSAlaW4lIGRhdGFzZXRzXSAlPiUKICAgIGFzLmRhdGEuZnJhbWUoKSAgI0lNUE9SVEFOVCBPdXRwdXQgYSBkYXRhZnJhbWUsIG5vdCBhIHRpYmJsZQoKIyAgSG93IGRvIHRoaW5ncyBsb29rPwpjb3VudHNfZGF0YQpgYGAKPGJyIC8+CgojIyMgTWFrZSB0aGUgbW9kZWwgbWF0cml4CmBgYHtyIG1ha2UgbW9kZWwgbWF0cml4LCBlY2hvPUZBTFNFLCByZXN1bHRzPSdoaWRlJywgbWVzc2FnZT1GQUxTRX0KIyAgVXNlIHRoZSAia2V5cyIgY29sdW1uIHRvIGlzb2xhdGUgZGF0YXNldHMgb2YgaW50ZXJlc3QKI1JFTUVNQkVSIFZhcmlhYmxlIGRhdGFzZXRzIGlzIGluaXRpYWxpemVkIGluIHRoZSBwcmVjZWRpbmcgY29kZSBjaHVuayAKY29sX2RhdGEgPC0gc2FtcGxlc1tzYW1wbGVzJGtleXMgJWluJSBkYXRhc2V0cywgXSAlPiUKICAgIGFzLmRhdGEuZnJhbWUoKSAlPiUgICNJTVBPUlRBTlQgT3V0cHV0IGEgZGF0YWZyYW1lLCBub3QgYSB0aWJibGUKICAgIHRpYmJsZTo6Y29sdW1uX3RvX3Jvd25hbWVzKC4sIHZhciA9ICJrZXlzIikgJT4lCiAgICBkcm9wbGV2ZWxzKCkKCiMgIE1ha2UgTmFiMy1kZXBsZXRpb24gbnVtZXJhdG9yLCBPc1RJUi1kZXBsZXRpb24gZGVub21pbmF0b3IgYnkgZXhwbGljaXRseQojKyByZW9yZGVyaW5nIHRoZSBsZXZlbHMgb2YgdGhlIGZhY3RvciBjb2xfZGF0YSRzdHJhaW4KY29sX2RhdGEkc3RyYWluIDwtIGZhY3Rvcihjb2xfZGF0YSRzdHJhaW4sIGxldmVscyA9IGMoIm8tZCIsICJuMy1kIikpCgojICBIb3cgZG8gdGhpbmdzIGxvb2s/CmNvbF9kYXRhCmNvbF9kYXRhJHN0cmFpbgpgYGAKPGJyIC8+CgojIyMgTWFrZSB0aGUgYERFU2VxRGF0YVNldGAsIGBkZHNgCi0gVXNlIGBjb3VudHNfZGF0YWAgZm9yIHRoZSBgZmVhdHVyZUNvdW50YCB0YWxsaWVzCi0gVXNlIGBjb2xfZGF0YWAgZm9yIHNldHRpbmcgdXAgdGhlIEdMTQotIFVzZSBgcG9zX2luZm9gIGZvciBhZGRpbmcgZmVhdHVyZSBtZXRhZGF0YSwgc3Vic2VxdWVudCBzdWJzZXR0aW5nLCBldGMuCgpgYGB7ciBNYWtlIHRoZSBERVNlcURhdGFTZXQsIG1lc3NhZ2U9RkFMU0V9CmRkcyA8LSBERVNlcTI6OkRFU2VxRGF0YVNldEZyb21NYXRyaXgoCiAgICBjb3VudERhdGEgPSBjb3VudHNfZGF0YSwKICAgIGNvbERhdGEgPSBjb2xfZGF0YSwKICAgIGRlc2lnbiA9IH4gc3RyYWluLCAgIyBWYXJ5IG9uIHN0cmFpbjogbjMtZCB2cyBvLWQKICAgIHJvd1JhbmdlcyA9IHBvc19pbmZvCikKCiMgIE1ha2UgYSBiYWNrLXVwIG9mIHRoZSBERVNlcURhdGFTZXQgb2JqZWN0CmJhay5kZHMgPC0gZGRzCgojICBIb3cgZG8gdGhpbmdzIGxvb2s/CiMgZGRzICU+JSBCaW9jR2VuZXJpY3M6OmNvdW50cygpICU+JSBoZWFkKCkKIyBkZHNAcm93UmFuZ2VzCiMgZGRzQGRlc2lnbgojIGRkc0Bhc3NheXMKYGBgCjxiciAvPgoKIyMjIFByZWZpbHRlciBgZGRzYApgI1RPRE9gIExldCdzIGtlZXAgdGhpcyBpbiBtaW5kIGFuZCB0cnkgaXQgaWYgd2UgY29tZSB0byB0aGluayBsb3dseSBleHByZXNzZWQKZ2VuZXMgYXJlIHNrZXdpbmcgcmVzdWx0cy4KCmBgYHtyIHByZWZpbHRlciBkZHMsIGVjaG89VFJVRSwgcmVzdWx0cz0naGlkZScsIG1lc3NhZ2U9RkFMU0V9CiMgdGhyZXNob2xkIDwtIDEwMDAKIyBkZHNfZmlsdCA8LSBkZHNbcm93U3VtcyhCaW9jR2VuZXJpY3M6OmNvdW50cyhkZHMpKSA+PSB0aHJlc2hvbGQsIF0KIyAKIyAgQnJlYWtkb3duCiMgICAgMCAxMzE2NgojICAgIDEgMTI4MjIKIyAgICAyIDEyNzE5CiMgICAgNSAxMjU0MAojICAgMTAgMTIzNTgKIyAgIDIwIDEyMTQ0CiMgICA1MCAxMTc2NAojICAxMDAgMTE0MDMKIyAgMjAwIDEwOTI3CiMgIDUwMCAxMDAxNQojIDEwMDAgODgyMgojIAojIHJtKHRocmVzaG9sZCwgZGRzX2ZpbHQpCmBgYAo8YnIgLz4KPGJyIC8+CgojIyBJLiBSdW4gUENBLCBldGMuCiMjIyBHZW5lcmF0ZSBub24tbm9ybWFsaXplZCBjb3VudHMKYGBge3IgSS4gR2VuZXJhdGUgbm9uLW5vcm1hbGl6ZWQgY291bnRzLCBtZXNzYWdlPUZBTFNFfQpub3JtX25vbiA8LSBkZHNbZGRzQHJvd1JhbmdlcyRnZW5vbWUgPT0gIlNfY2VyZXZpc2lhZSIsIF0gJT4lCiAgICBTdW1tYXJpemVkRXhwZXJpbWVudDo6YXNzYXkoKSAlPiUKICAgIGFzLmRhdGEuZnJhbWUoKQpub3JtX25vbiRmZWF0dXJlX2luaXQgPC0gZGRzQHJvd1JhbmdlcyRmZWF0dXJlX2luaXRbCiAgICBkZHNAcm93UmFuZ2VzJGdlbm9tZSA9PSAiU19jZXJldmlzaWFlIgpdCgojICBBc3NvY2lhdGUgbm9uLW5vcm1hbGl6ZWQgdmFsdWVzIHdpdGggZmVhdHVyZSBtZXRhZGF0YQpub3JtX25vbiA8LSBkcGx5cjo6ZnVsbF9qb2luKAogICAgbm9ybV9ub24sCiAgICB0X2ZjWyh0X2ZjJGdlbm9tZSA9PSAiU19jZXJldmlzaWFlIiksIDE6OV0sCiAgICBieSA9ICJmZWF0dXJlX2luaXQiCikgJT4lCiAgICBkcGx5cjo6YXNfdGliYmxlKCkKYGBgCjxiciAvPgoKIyMjIEdlbmVyYXRlIG5vcm1hbGl6ZWQgY291bnRzCiMjIyMgQ2FsY3VsYXRlIHJsb2ctbm9ybWFsaXplZCAodW5ibGluZGVkKSBjb3VudHMKYGBge3IgSS4gQ3JlYXRlIHJsb2ctbm9ybWFsaXplZCBjb3VudHMsIG1lc3NhZ2U9RkFMU0V9Cm5vcm1fciA8LSBERVNlcTI6OnJsb2coCiAgICBkZHNbZGRzQHJvd1JhbmdlcyRnZW5vbWUgPT0gIlNfY2VyZXZpc2lhZSIsIF0sCiAgICBibGluZCA9IEZBTFNFCikgJT4lCiAgICBTdW1tYXJpemVkRXhwZXJpbWVudDo6YXNzYXkoKSAlPiUKICAgIGFzLmRhdGEuZnJhbWUoKQpub3JtX3IkZmVhdHVyZV9pbml0IDwtIGRkc0Byb3dSYW5nZXMkZmVhdHVyZV9pbml0WwogICAgZGRzQHJvd1JhbmdlcyRnZW5vbWUgPT0gIlNfY2VyZXZpc2lhZSIKXQoKIyAgQXNzb2NpYXRlIG5vcm1hbGl6ZWQgdmFsdWVzIHdpdGggZmVhdHVyZSBtZXRhZGF0YQpub3JtX3IgPC0gZHBseXI6OmZ1bGxfam9pbigKICAgIG5vcm1fciwKICAgIHRfZmNbdF9mYyRnZW5vbWUgPT0gIlNfY2VyZXZpc2lhZSIsIDE6OV0sCiAgICBieSA9ICJmZWF0dXJlX2luaXQiCikgJT4lCiAgICBkcGx5cjo6YXNfdGliYmxlKCkKYGBgCjxiciAvPgoKIyMjIyBDYWxjdWxhdGUgR2VUTU0tbm9ybWFsaXplZCBjb3VudHMKTW9yZSBkZXRhaWxzIG9uIHRoaXMgcmVsYXRpdmVseSBuZXcgbWV0aG9kIG9mIG5vcm1hbGl6YXRpb24sIHdoaWNoIGNvbWJpbmVzCmludGVyLSBhbmQgaW50cmEtc2FtcGxlIG5vcm1hbGl6YXRpb24gbWV0aG9kcyBhbmQgKGFwcGVhcnMgdG8pIHBlcmZvcm0gcXVpdGUKd2VsbDoKCi0gW0JhcmFpa2RhciBldCBhbC4gKFRydXR0bWFubiksICpFeHAgR2Vyb250b2wqIDIwMjNdKGh0dHBzOi8vd3d3LnNjaWVuY2VkaXJlY3QuY29tL3NjaWVuY2UvYXJ0aWNsZS9waWkvUzA1MzE1NTY1MjMwMDAyODEpCi0gW0JhcnJldHQgZXQgYWwuIChIYW1tYXJsdW5kKSwgKkczKiAyMDIxXShodHRwczovL2FjYWRlbWljLm91cC5jb20vZzNqb3VybmFsL2FydGljbGUvMTEvNy9qa2FiMTIxLzYyMjY0ODUpCi0gW0JlZHJlLCAqc2VsZi1wdWJsaXNoZWQqIDIwMjMgKG1vc3QgcmVjZW50IHVwZGF0ZSldKGh0dHBzOi8vd3d3LnJlbmVzaGJlZHJlLmNvbS9ibG9nL2V4cHJlc3Npb25fdW5pdHMuaHRtbCNnZXRtbS1tZXRob2QpCi0gW05lbHNvbiBldCBhbC4gKFdpbGtpbnMpLCAqTmF0IE1pY3JvYmlvbCogMjAyMl0oaHR0cHM6Ly93d3cubmNiaS5ubG0ubmloLmdvdi9wbWMvYXJ0aWNsZXMvUE1DOTQxODAwMS8pCi0gW1NtaWQgZXQgYWwuIChTaWV1d2VydHMpLCAqQk1DIEJpb2luZiogMjAxOF0oaHR0cHM6Ly9ibWNiaW9pbmZvcm1hdGljcy5iaW9tZWRjZW50cmFsLmNvbS9hcnRpY2xlcy8xMC4xMTg2L3MxMjg1OS0wMTgtMjI0Ni03KQotIFtXYWxrZXIgZXQgYWwuIChLYWluZXIpLCAqQ29tcHV0IFN0cnVjdCBCaW90ZWNobm9sIEoqIDIwMjJdKGh0dHBzOi8vd3d3Lm5jYmkubmxtLm5paC5nb3YvcG1jL2FydGljbGVzL1BNQzkyNjAyNjAvKQotIFtaYXR6bWFuIGV0IGFsLiAoU2hsaWVuKSwgKlNjaSBBZHYqIDIwMjJdKGh0dHBzOi8vd3d3Lm5jYmkubmxtLm5paC5nb3YvcG1jL2FydGljbGVzL1BNQzk2ODM3MjMvKQoKYGBge3IgSS4gQ3JlYXRlIEdlVE1NLW5vcm1hbGl6ZWQgY291bnRzLCBtZXNzYWdlPUZBTFNFfQojICBJc29sYXRlIHJhdyBjb3VudHMgZm9yIHNhbXBsZXMgb2YgaW50ZXJlc3QKcmF3IDwtIGRkcyAlPiUKICAgIFN1bW1hcml6ZWRFeHBlcmltZW50Ojphc3NheSgpICU+JQogICAgYXMuZGF0YS5mcmFtZSgpCnJhdyRmZWF0dXJlX2luaXQgPC0gZGRzQHJvd1JhbmdlcyRmZWF0dXJlX2luaXQKCiMgIEFzc29jaWF0ZSBub24tbm9ybWFsaXplZCB2YWx1ZXMgd2l0aCBmZWF0dXJlIG1ldGFkYXRhCnJhdyA8LSBkcGx5cjo6ZnVsbF9qb2luKAogICAgcmF3LAogICAgdF9mY1ssIGMoc2VxKDEsOSkpXSwKICAgIGJ5ID0gImZlYXR1cmVfaW5pdCIKKSAlPiUKICAgIGRwbHlyOjphc190aWJibGUoKQoKIyAgQ2FsY3VsYXRlIGNvdW50cyBwZXIga2Igb2YgZ2VuZSBsZW5ndGggKGkuZS4sIGNvcnJlY3QgY291bnRzIGZvciBnZW5lCiMrIGxlbmd0aCk7IGdlbmUgbGVuZ3RoIGlzIGluaXRpYWxseSBpbiBicCBhbmQgY29udmVydGVkIHRvIGtiCnJwayA8LSAoKHJhd1ssIDE6NV0gKiAxMF4zKSAvIHJhdyRsZW5ndGgpCnJwa1ssIDY6MTRdIDwtIHJhd1ssIDY6MTRdCgojICBDYWxjdWxhdGUgbm9ybWFsaXphdGlvbiBmYWN0b3JzIHVzaW5nIHRoZSByYXcgc3Bpa2UtaW4gKEsuIGxhY3RpcykgY291bnRzCm5vcm1fS0wgPC0gZWRnZVI6OmNhbGNOb3JtRmFjdG9ycygKICAgIHJhd1socnBrJGdlbm9tZSA9PSAiS19sYWN0aXMiKSwgXVssIDE6NV0KKQoKIyAgQ3JlYXRlIGZhY3RvciBmb3IgY2F0ZWdvcmllcyAoZ3JvdXBzKQptb2RlbF92YXJpYWJsZXMgPC0gc3RyaW5ncjo6c3RyX3NwbGl0KGNvbG5hbWVzKHJwa1ssIDE6NV0pLCAiXyIpICU+JQogICAgYXMuZGF0YS5mcmFtZSgKICAgICAgICByb3cubmFtZXMgPSBjKAogICAgICAgICAgICAic2FtcGxlIiwgInN0YWdlIiwgImRheSIsICJraXQiLCAidHgiLCAiYXV4IiwgInRjIiwgInJlcCIsICJ0ZWNoIgogICAgICAgICksCiAgICAgICAgY29sLm5hbWVzID0gcGFzdGUwKCJzIiwgYygxOjUpKQogICAgKSAlPiUKICAgIHQoKSAlPiUKICAgIHRpYmJsZTo6YXNfdGliYmxlKCkKCmdyb3VwIDwtIGZhY3RvcigKICAgICMgU2Vjb25kIGxldmVsIGlzIG51bWVyYXRvciwgZmlyc3QgbGV2ZWwgaXMgZGVub21pbmF0b3IKICAgIG1vZGVsX3ZhcmlhYmxlcyRzYW1wbGUsCiAgICBsZXZlbHMgPSBjKCJvLWQiLCAibjMtZCIpCikKCnJtKG1vZGVsX3ZhcmlhYmxlcykKCiMgIENyZWF0ZSBlZGdlUiBER0VMaXN0IG9iamVjdCBjb21wb3NlZCBvZiBTLiBjZXJldmlzaWFlIGNvdW50cyBwZXIga2IgZ2VuZQojKyBsZW5ndGgKZGdlbCA8LSBlZGdlUjo6REdFTGlzdCgKICAgIGNvdW50cyA9IHJwa1tycGskZ2Vub21lID09ICJTX2NlcmV2aXNpYWUiLCBdWywgMTo1XSwKICAgIGdyb3VwID0gZ3JvdXAKKQoKIyAgSW4gdGhlIERHRUxpc3Qgb2JqZWN0LCBpbmNsdWRlIHRoZSBub3JtYWxpemF0aW9uIGZhY3RvcnMgY2FsY3VsYXRlZCBmcm9tCiMrIHNwaWtlLWluIGluZm9ybWF0aW9uCmRnZWwkc2FtcGxlcyRub3JtLmZhY3RvcnMgPC0gbm9ybV9LTAoKIyAgQ2hlY2sgdGhhdCB0aGUgbm9ybWFsaXphdGlvbiBmYWN0b3JzIGZvciBlYWNoIGxpYnJhcnkgYXJlIGFwcHJvcHJpYXRlbHkKIysgYXNzaWduZWQKZGdlbCRzYW1wbGVzCgojICBTY2FsZSB0aGUgdmFsdWVzIHRvIGNvdW50cy1wZXItbWlsbGlvbgpub3JtX2cgPC0gZWRnZVI6OmNwbShkZ2VsKSAlPiUgdGliYmxlOjphc190aWJibGUoKQpub3JtX2dbLCA2OjE0XSA8LSBycGtbcnBrJGdlbm9tZSA9PSAiU19jZXJldmlzaWFlIiwgNjoxNF0Kbm9ybV9nCgojICBDbGVhbiB1cCB1bm5lZWRlZCB2YXJpYWJsZXMKcm0ocmF3LCBycGssIG5vcm1fS0wsIGdyb3VwKQpybShkZ2VsKSAgI1RPRE8gRGVsZXRlIGRnZWw/IE9yIHVzZSBpdCBmb3IgdHJ5aW5nIG91dCBERSBhbmFseXNlcyB3aXRoIGVkZ2VSPwpgYGAKPGJyIC8+CgojIyMjIENhbGN1bGF0ZSBUUE0tbm9ybWFsaXplZCBjb3VudHMKYGBge3IgSS4gQ2FsY3VsYXRlIFRQTS1ub3JtYWxpemVkIGNvdW50cywgbWVzc2FnZT1GQUxTRX0KIyAgSXNvbGF0ZSByYXcgY291bnRzIGZvciBzYW1wbGVzIG9mIGludGVyZXN0CnJhdyA8LSBkZHMgJT4lCiAgICBTdW1tYXJpemVkRXhwZXJpbWVudDo6YXNzYXkoKSAlPiUKICAgIGFzLmRhdGEuZnJhbWUoKQpyYXckZmVhdHVyZV9pbml0IDwtIGRkc0Byb3dSYW5nZXMkZmVhdHVyZV9pbml0CgojICBBc3NvY2lhdGUgbm9uLW5vcm1hbGl6ZWQgdmFsdWVzIHdpdGggZmVhdHVyZSBtZXRhZGF0YQpyYXcgPC0gZHBseXI6OmZ1bGxfam9pbigKICAgIHJhdywKICAgIHRfZmNbLCAxOjldLAogICAgYnkgPSAiZmVhdHVyZV9pbml0IgopICU+JQogICAgZHBseXI6OmFzX3RpYmJsZSgpCgojICBDYWxjdWxhdGUgY291bnRzIHBlciBrYiBvZiBnZW5lIGxlbmd0aCAoaS5lLiwgY29ycmVjdCBjb3VudHMgZm9yIGdlbmUKIysgbGVuZ3RoIG9yIGRvIGFuICJSUEsgbm9ybWFsaXphdGlvbiIpOyB0aGVuLCBkaXZpZGUgUlBLLW5vcm1hbGl6ZWQgZWxlbWVudHMKIysgYnkgdGhlIHN1bSBvZiBzYW1wbGUgUlBLIGRpdmlkZWQgYnkgb25lIG1pbGxpb246IHRoaXMgZG9lcyB0aGUgYWN0dWFsIFRQTQojKyBub3JtYWxpemF0aW9uCnJwayA8LSB0cG0gPC0gKChyYXdbLCAxOjVdICogMTBeMykgLyByYXckbGVuZ3RoKQpmb3IgKGkgaW4gMTpuY29sKHJwaykpIHsKICAgIHRwbVssIGldIDwtIChycGtbLCBpXSAvIHN1bShycGtbLCBpXSAvIDFlNikpCn0KCnRwbVssIDY6MTRdIDwtIHJhd1ssIDY6MTRdCm5vcm1fdCA8LSB0cG1bdHBtJGdlbm9tZSA9PSAiU19jZXJldmlzaWFlIiwgXQoKcm0ocmF3LCBycGssIHRwbSkKYGBgCjxiciAvPgoKIyMjIFJ1biBQQ0Egd2l0aCB2YXJpb3VzbHkgbm9ybWFsaXplZCBjb3VudHMKIyMjIyBQYXJ0IDEKYGBge3IgSS4gUnVuIFBDQSB3aXRoIHZhcmlvdXNseSBub3JtYWxpemVkIGNvdW50cyAocGFydCAxKSwgbWVzc2FnZT1GQUxTRX0KIyAgTWFrZSB0aGUgZm9sbG93aW5nIGNvZGUgZ2VuZXJpYyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojKyAuLi5zbyB0aGF0IHdlIGNhbiB0cnkgaXQgd2l0aCBkaWZmZXJlbnQgbm9ybWFsaXphdGlvbiBvYmplY3RzIChjb3VudHMKIysgbm9ybWFsaXplZCBpbiBkaWZmZXJlbnQgd2F5cykKIyBub3JtIDwtIG5vcm1fbm9uCm5vcm0gPC0gbm9ybV9yCiMgbm9ybSA8LSBub3JtX2cKIyBub3JtIDwtIG5vcm1fdAoKCiMgIENyZWF0ZSBhIFBDQXRvb2xzICJwY2EiIFM0IG9iamVjdCBmb3IgdGhlIG5vcm1hbGl6ZWQgY291bnRzIC0tLS0tLS0tLS0tLS0tLS0KIysgQXNzaWduIHVuaXF1ZSByb3cgbmFtZXMgdG9vCm9ial9wY2EgPC0gUENBdG9vbHM6OnBjYSgKICAgIG5vcm1bLCBjKDE6NSldLAogICAgbWV0YWRhdGEgPSBkZHNbZGRzQHJvd1JhbmdlcyRnZW5vbWUgIT0gIktfbGFjdGlzIiwgXUBjb2xEYXRhCikKcm93bmFtZXMob2JqX3BjYSRsb2FkaW5ncykgPC0gbWFrZS5uYW1lcygKICAgIGRkc1tkZHNAcm93UmFuZ2VzJGdlbm9tZSAhPSAiS19sYWN0aXMiLCBdQHJvd1JhbmdlcyRmZWF0dXJlLAogICAgdW5pcXVlID0gVFJVRQopCgoKIyAgRGV0ZXJtaW5lICJzaWduaWZpY2FudCIgUENzIHdpdGggSG9ybidzIHBhcmFsbGVsIGFuYWx5c2lzIC0tLS0tLS0tLS0tLS0tLS0tLQojKyBTZWUgSG9ybiwgMTk2NQpob3JuIDwtIFBDQXRvb2xzOjpwYXJhbGxlbFBDQShtYXQgPSBzYXBwbHkobm9ybVssIGMoMTo1KV0sIGFzLmRvdWJsZSkpCgoKIyAgRGV0ZXJtaW5lICJzaWduaWZpY2FudCIgcHJpbmNpcGxlIGNvbXBvbmVudHMgd2l0aCB0aGUgZWxib3cgbWV0aG9kIC0tLS0tLS0tLQojKyBTZWUgQnVqYSBhbmQgRXl1Ym9nbHUsIDE5OTIKZWxib3cgPC0gUENBdG9vbHM6OmZpbmRFbGJvd1BvaW50KG9ial9wY2EkdmFyaWFuY2UpCgoKIyAgRXZhbHVhdGUgY3VtdWxhdGl2ZSBwcm9wb3J0aW9uIG9mIGV4cGxhaW5lZCB2YXJpYW5jZSB3aXRoIGEgc2NyZWUgcGxvdCAtLS0tLQpzY3JlZSA8LSBkcmF3X3NjcmVlX3Bsb3Qob2JqX3BjYSwgaG9ybiA9IGhvcm4kbiwgZWxib3cgPSBlbGJvdykKc2NyZWUKIyBzYXZlX3RpdGxlIDwtIHBhc3RlMCgicGFuZWwtcGxvdCIsICIuIiwgInNjcmVlIiwgIi5wZGYiKQojIGdncGxvdDI6Omdnc2F2ZShwYXN0ZTAoYXJncyRkaXJlY3Rvcnlfb3V0LCAiLyIsIHNhdmVfdGl0bGUpLCBzY3JlZSkKI1RPRE8gV29yayB1cCBzb21lIGxvZ2ljIGZvciBvdXRmaWxlIG5hbWVzLCBsb2NhdGlvbihzKSBmb3Igb3V0ZmlsZXMsIGV0Yy4KCgojICBTYXZlIGNvbXBvbmVudCBsb2FkaW5nIHZlY3RvcnMgaW4gdGhlaXIgb3duIGRhdGEgZnJhbWUgLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmxvYWRpbmdzIDwtIGFzLmRhdGEuZnJhbWUob2JqX3BjYSRsb2FkaW5ncykKCiMgIEV2YWx1YXRlIHRoZSBjb21wb25lbnQgbG9hZGluZyB2ZWN0b3JzIGZvciB0aGUgbnVtYmVyIG9mIHNpZ25pZmljYW50IFBDcwojKyBpZGVudGlmaWVkIHZpYSB0aGUgZWxib3cgbWV0aG9kIHBsdXMgdHdvClBDcyA8LSBwYXN0ZTAoIlBDIiwgMTooYXMubnVtZXJpYyhlbGJvdykgKyAyKSkKdG9wX2xvYWRpbmdzX2FsbCA8LSBsYXBwbHkoCiAgICBQQ3MsIGdldF90b3BfbG9hZGluZ3MsIHggPSBsb2FkaW5ncywgeiA9ICJhbGwiLCBhID0gVFJVRQopCnRvcF9sb2FkaW5nc19wb3MgPC0gbGFwcGx5KAogICAgUENzLCBnZXRfdG9wX2xvYWRpbmdzLCB4ID0gbG9hZGluZ3MsIHogPSAicG9zIiwgYSA9IFRSVUUKKQp0b3BfbG9hZGluZ3NfbmVnIDwtIGxhcHBseSgKICAgIFBDcywgZ2V0X3RvcF9sb2FkaW5ncywgeCA9IGxvYWRpbmdzLCB6ID0gIm5lZyIsIGEgPSBUUlVFCikKCm5hbWVzKHRvcF9sb2FkaW5nc19hbGwpIDwtCiAgICBuYW1lcyh0b3BfbG9hZGluZ3NfcG9zKSA8LQogICAgbmFtZXModG9wX2xvYWRpbmdzX25lZykgPC0KICAgIFBDcwojIHJtKFBDcykKIyB0b3BfbG9hZGluZ3NfYWxsJFBDMSAlPiUgaGVhZChuID0gMjApCiMgdG9wX2xvYWRpbmdzX3BvcyRQQzEgJT4lIGhlYWQobiA9IDIwKQojIHRvcF9sb2FkaW5nc19uZWckUEMxICU+JSBoZWFkKG4gPSAyMCkKCgojICBBbmFseXplIHBvc2l0aXZlLCBuZWdhdGl2ZSBsb2FkaW5ncyBvbiBheGVzIG9mIGJpcGxvdHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMrIExvb2sgYXQgdGhlIHRvcCAxNSBwZXIgYXhpcwppbWFnZXMgPC0gbGlzdCgpCm1hdCA8LSBjb21ibihQQ3MsIDIpCmZvcihpIGluIDE6bmNvbChtYXQpKSB7CiAgICAjIGkgPC0gMQogICAgaiA8LSBtYXRbLCBpXQogICAgCiAgICBQQ194IDwtIHhfbGFiZWwgPC0galsxXQogICAgUENfeSA8LSB5X2xhYmVsIDwtIGpbMl0KICAgIAogICAgaW1hZ2VzW1twYXN0ZTAoIlBDQXRvb2xzLiIsIFBDX3gsICIudi4iLCBQQ195KV1dIDwtIHBsb3RfYmlwbG90KAogICAgICAgIHBjYSA9IG9ial9wY2EsCiAgICAgICAgUENfeCA9IFBDX3gsCiAgICAgICAgUENfeSA9IFBDX3ksCiAgICAgICAgbG9hZGluZ3Nfc2hvdyA9IEZBTFNFLAogICAgICAgIGxvYWRpbmdzX24gPSAwLAogICAgICAgIG1ldGFfY29sb3IgPSAic3RyYWluIiwKICAgICAgICBtZXRhX3NoYXBlID0gInJlcGxpY2F0ZSIsCiAgICAgICAgeF9taW4gPSAtMTAwLAogICAgICAgIHhfbWF4ID0gMTAwLAogICAgICAgIHlfbWluID0gLTEwMCwKICAgICAgICB5X21heCA9IDEwMAogICAgKQogICAgIyAgeCBhbmQgeSByYW5nZXMgZm9yIG5vbi1ub3JtYWxpemVkIGNvdW50cwogICAgIysgeF9taW4gPSAtMjAwMDAwLAogICAgIysgeF9tYXggPSAyMDAwMDAsCiAgICAjKyB5X21pbiA9IC0yMDAwMDAsCiAgICAjKyB5X21heCA9IDIwMDAwMAogICAgIysKICAgICMrIHggYW5kIHkgcmFuZ2VzIGZvciBybG9nLW5vcm1hbGl6ZWQgY291bnRzCiAgICAjKyB4X21pbiA9IC01MCwKICAgICMrIHhfbWF4ID0gNTAsCiAgICAjKyB5X21pbiA9IC01MCwKICAgICMrIHlfbWF4ID0gNTAKICAgICMrCiAgICAjKyB4IGFuZCB5IHJhbmdlcyBmb3IgR2VUTU0tbm9ybWFsaXplZCBjb3VudHMKICAgICMrIHhfbWluID0gLTUwMDAwLAogICAgIysgeF9tYXggPSA1MDAwMCwKICAgICMrIHlfbWluID0gLTUwMDAwLAogICAgIysgeV9tYXggPSA1MDAwMAogICAgIysKICAgICMrIHggYW5kIHkgcmFuZ2VzIGZvciBUUE0tbm9ybWFsaXplZCBjb3VudHMKICAgICMrIHhfbWluID0gLTEwMDAwLAogICAgIysgeF9tYXggPSAxMDAwMCwKICAgICMrIHlfbWluID0gLTEwMDAwLAogICAgIysgeV9tYXggPSAxMDAwMAogICAgCiAgICAjREVDSVNJT04gRm9yIG5vdywgZ28gd2l0aCBybG9nIGFuZCBUUE07IGNvbnRpbnVlIHRvIHRlc3QgYWxsIGZvdXIKICAgIAogICAgaW1hZ2VzW1twYXN0ZTAoIktBLiIsIFBDX3gsICIudi4iLCBQQ195KV1dIDwtCiAgICAgICAgcGxvdF9wb3NfbmVnX2xvYWRpbmdzX2VhY2hfYXhpcygKICAgICAgICAgICAgZGZfYWxsID0gbG9hZGluZ3MsCiAgICAgICAgICAgIGRmX3BvcyA9IHRvcF9sb2FkaW5nc19wb3MsCiAgICAgICAgICAgIGRmX25lZyA9IHRvcF9sb2FkaW5nc19uZWcsCiAgICAgICAgICAgIFBDX3ggPSBQQ194LAogICAgICAgICAgICBQQ195ID0gUENfeSwKICAgICAgICAgICAgcm93X3N0YXJ0ID0gMSwKICAgICAgICAgICAgcm93X2VuZCA9IDE1LCAgIyAzMAogICAgICAgICAgICB4X21pbiA9IC0wLjEsCiAgICAgICAgICAgIHhfbWF4ID0gMC4xLAogICAgICAgICAgICB5X21pbiA9IC0wLjEsCiAgICAgICAgICAgIHlfbWF4ID0gMC4xLAogICAgICAgICAgICB4X251ZGdlID0gMC4wMiwKICAgICAgICAgICAgeV9udWRnZSA9IDAuMDQsCiAgICAgICAgICAgIHhfbGFiZWwgPSB4X2xhYmVsLAogICAgICAgICAgICB5X2xhYmVsID0geV9sYWJlbCwKICAgICAgICAgICAgY29sX2xpbmVfcG9zID0gImJsYWNrIiwKICAgICAgICAgICAgY29sX2xpbmVfbmVnID0gInJlZCIsCiAgICAgICAgICAgIGNvbF9zZWdfcG9zID0gImdyZXkiLAogICAgICAgICAgICBjb2xfc2VnX25lZyA9ICJncmV5IgogICAgICAgICkKICAgICMgIHggYW5kIHkgcmFuZ2VzIChldGMuKSBmb3Igbm9uLW5vcm1hbGl6ZWQgY291bnRzIChtZXNzeSkKICAgICMrIHhfbWluID0gLTAuNzUsCiAgICAjKyB4X21heCA9IDAuNzUsCiAgICAjKyB5X21pbiA9IC0wLjMzLAogICAgIysgeV9tYXggPSAwLjMzLAogICAgIysgeF9udWRnZSA9IDAuMDIsCiAgICAjKyB5X251ZGdlID0gMC4wNCwKICAgICMrCiAgICAjICB4IGFuZCB5IHJhbmdlcyAoZXRjLikgZm9yIHJsb2ctbm9ybWFsaXplZCBjb3VudHMgKG5pY2UgYW5kIGNsZWFuKQogICAgIysgeF9taW4gPSAtMC4xLAogICAgIysgeF9tYXggPSAwLjEsCiAgICAjKyB5X21pbiA9IC0wLjEsCiAgICAjKyB5X21heCA9IDAuMSwKICAgICMrIHhfbnVkZ2UgPSAwLjAyLAogICAgIysgeV9udWRnZSA9IDAuMDQsCiAgICAjKwogICAgIysgeCBhbmQgeSByYW5nZXMgKGV0Yy4pIGZvciBHZVRNTS1ub3JtYWxpemVkIGNvdW50cyAoYSBiaXQgbWVzc3kpCiAgICAjKyB4X21pbiA9IC0wLjUsCiAgICAjKyB4X21heCA9IDAuNSwKICAgICMrIHlfbWluID0gLTAuNSwKICAgICMrIHlfbWF4ID0gMC41LAogICAgIysgeF9udWRnZSA9IDAuMDQsCiAgICAjKyB5X251ZGdlID0gMC4wMiwKICAgICMrCiAgICAjKyB4IGFuZCB5IHJhbmdlcyAoZXRjLikgZm9yIFRQTS1ub3JtYWxpemVkIGNvdW50cyAoYSBiaXQgbGVzcyBtZXNzeSkKICAgICMrIHhfbWluID0gLTAuNSwKICAgICMrIHhfbWF4ID0gMC41LAogICAgIysgeV9taW4gPSAtMC41LAogICAgIysgeV9tYXggPSAwLjUsCiAgICAjKyB4X251ZGdlID0gMC4wNCwKICAgICMrIHlfbnVkZ2UgPSAwLjAyLAogICAgCiAgICBpbWFnZXNbW3Bhc3RlMCgiS0EuIiwgUENfeCwgIi52LiIsIFBDX3kpXV0KfQoKIyAgSG93IGRvIHRoaW5ncyBsb29rPwppbWFnZXMkUENBdG9vbHMuUEMxLnYuUEMyCmltYWdlcyRLQS5QQzEudi5QQzIkUENfeF9wb3MKaW1hZ2VzJEtBLlBDMS52LlBDMiRQQ194X25lZwppbWFnZXMkS0EuUEMxLnYuUEMyJFBDX3lfcG9zCmltYWdlcyRLQS5QQzEudi5QQzIkUENfeV9uZWcKIyBpbWFnZXMkUENBdG9vbHMuUEMxLnYuUEMzCiMgaW1hZ2VzJEtBLlBDMS52LlBDMwojIGltYWdlcyRQQ0F0b29scy5QQzEudi5QQzQKIyBpbWFnZXMkS0EuUEMxLnYuUEM0CiMgaW1hZ2VzJFBDQXRvb2xzLlBDMi52LlBDMwojIGltYWdlcyRLQS5QQzIudi5QQzMKYGBgCjxiciAvPgoKIyMjIyBQYXJ0IDIKYGBge3IgSS4gUnVuIFBDQSB3aXRoIHZhcmlvdXNseSBub3JtYWxpemVkIGNvdW50cyAocGFydCAyKSwgbWVzc2FnZT1GQUxTRX0KIyBmb3IoaSBpbiAxOmxlbmd0aChuYW1lcyhpbWFnZXMpKSkgewojICAgICAjIGkgPC0gMgojICAgICB2ZWN0b3JfbmFtZXMgPC0gbmFtZXMoaW1hZ2VzKSAlPiUgc3RyaW5ncjo6c3RyX3NwbGl0KCJcXC4iKQojICAgICAKIyAgICAgaWYodmVjdG9yX25hbWVzW1tpXV1bMV0gPT0gIlBDQXRvb2xzIikgewojICAgICAgICAgc2F2ZV90aXRsZSA8LSBwYXN0ZTAoInBhbmVsLXBsb3QiLCAiLiIsIG5hbWVzKGltYWdlcylbaV0sICIucGRmIikKIyAgICAgICAgIGdncGxvdDI6Omdnc2F2ZSgKIyAgICAgICAgICAgICBwYXN0ZTAoYXJncyRkaXJlY3Rvcnlfb3V0LCAiLyIsIHNhdmVfdGl0bGUpLCBpbWFnZXNbW2ldXQojICAgICAgICAgKQojICAgICB9IGVsc2UgaWYodmVjdG9yX25hbWVzW1tpXV1bMV0gPT0gIktBIikgewojICAgICAgICAgc2F2ZV90aXRsZSA8LSBwYXN0ZTAoCiMgICAgICAgICAgICAgInBhbmVsLXBsb3QiLCAiLiIsIG5hbWVzKGltYWdlcylbaV0sICIuMS14LXBvc2l0aXZlLnBkZiIKIyAgICAgICAgICkKIyAgICAgICAgIGdncGxvdDI6Omdnc2F2ZSgKIyAgICAgICAgICAgICBwYXN0ZTAoYXJncyRkaXJlY3Rvcnlfb3V0LCAiLyIsIHNhdmVfdGl0bGUpLCBpbWFnZXNbW2ldXVtbMV1dCiMgICAgICAgICApCiMgICAgICAgICAKIyAgICAgICAgIHNhdmVfdGl0bGUgPC0gcGFzdGUwKAojICAgICAgICAgICAgICJwYW5lbC1wbG90IiwgIi4iLCBuYW1lcyhpbWFnZXMpW2ldLCAiLjIteS1wb3NpdGl2ZS5wZGYiCiMgICAgICAgICApCiMgICAgICAgICBnZ3Bsb3QyOjpnZ3NhdmUoCiMgICAgICAgICAgICAgcGFzdGUwKGFyZ3MkZGlyZWN0b3J5X291dCwgIi8iLCBzYXZlX3RpdGxlKSwgaW1hZ2VzW1tpXV1bWzJdXQojICAgICAgICAgKQojICAgICAgICAgCiMgICAgICAgICBzYXZlX3RpdGxlIDwtIHBhc3RlMCgKIyAgICAgICAgICAgICAicGFuZWwtcGxvdCIsICIuIiwgbmFtZXMoaW1hZ2VzKVtpXSwgIi4zLXgtbmVnYXRpdmUucGRmIgojICAgICAgICAgKQojICAgICAgICAgZ2dwbG90Mjo6Z2dzYXZlKAojICAgICAgICAgICAgIHBhc3RlMChhcmdzJGRpcmVjdG9yeV9vdXQsICIvIiwgc2F2ZV90aXRsZSksIGltYWdlc1tbaV1dW1szXV0KIyAgICAgICAgICkKIyAgICAgICAgIAojICAgICAgICAgc2F2ZV90aXRsZSA8LSBwYXN0ZTAoCiMgICAgICAgICAgICAgInBhbmVsLXBsb3QiLCAiLiIsIG5hbWVzKGltYWdlcylbaV0sICIuNC15LW5lZ2F0aXZlLnBkZiIKIyAgICAgICAgICkKIyAgICAgICAgIGdncGxvdDI6Omdnc2F2ZSgKIyAgICAgICAgICAgICBwYXN0ZTAoYXJncyRkaXJlY3Rvcnlfb3V0LCAiLyIsIHNhdmVfdGl0bGUpLCBpbWFnZXNbW2ldXVtbNF1dCiMgICAgICAgICApCiMgICAgIH0KIyB9CiNUT0RPIFdvcmsgdXAgc29tZSBsb2dpYyBmb3Igb3V0ZmlsZSBuYW1lcywgbG9jYXRpb24ocykgZm9yIG91dGZpbGVzCgoKIyAgUGxvdCB0aGUgdG9wIGZlYXR1cmVzIG9uIGFuIGF4aXMgb2YgY29tcG9uZW50IGxvYWRpbmcgcmFuZ2UgLS0tLS0tLS0tLS0tLS0tLQojKyAuLi50byB2aXN1YWxpemUgdGhlIHRvcCB2YXJpYWJsZXMgKGZlYXR1cmVzKSB0aGF0IGRyaXZlIHZhcmlhbmNlIGFtb25nCiMrIHByaW5jaXBhbCBjb21wb25lbnRzIG9mIGludGVyZXN0CnBfbG9hZGluZ3MgPC0gUENBdG9vbHM6OnBsb3Rsb2FkaW5ncygKICAgIG9ial9wY2EsCiAgICBjb21wb25lbnRzID0gZ2V0Q29tcG9uZW50cyhvYmpfcGNhLCAxKSwKICAgICMgY29tcG9uZW50cyA9IGdldENvbXBvbmVudHMob2JqX3BjYSwgMTo1KSwKICAgIHJhbmdlUmV0YWluID0gMC4wNSwKICAgIGFic29sdXRlID0gRkFMU0UsCiAgICBjb2wgPSBjKCIjNzg1RUYwNzUiLCAiI0ZGRkZGRjc1IiwgIiNGRTYxMDA3NSIpLAogICAgdGl0bGUgPSAiTG9hZGluZ3MgcGxvdCIsCiAgICBzdWJ0aXRsZSA9ICJUb3AgNSUgb2YgdmFyaWFibGVzIChpLmUuLCBmZWF0dXJlcykiLAogICAgIyBzaGFwZVNpemVSYW5nZSA9IGMoNCwgMTYpLAogICAgYm9yZGVyQ29sb3VyID0gIiMwMDAwMDAiLAogICAgYm9yZGVyV2lkdGggPSAwLjIsCiAgICBncmlkbGluZXMubWFqb3IgPSBUUlVFLAogICAgZ3JpZGxpbmVzLm1pbm9yID0gVFJVRSwKICAgIGF4aXNMYWJTaXplID0gMTAsCiAgICBsYWJTaXplID0gMywgICMgbGFiZWxfc2l6ZQogICAgZHJhd0Nvbm5lY3RvcnMgPSBUUlVFLAogICAgd2lkdGhDb25uZWN0b3JzID0gMC4yLAogICAgdHlwZUNvbm5lY3RvcnMgPSAnY2xvc2VkJywKICAgIGNvbENvbm5lY3RvcnMgPSAnYmxhY2snCikgKwogICAgIyBnZ3Bsb3QyOjpjb29yZF9mbGlwKCkgKwogICAgdGhlbWVfc2xpY2tfbm9fbGVnZW5kCnBfbG9hZGluZ3MKI1RPRE8gV29yayB1cCBzb21lIGxvZ2ljIGZvciBzYXZpbmcgdGhlIHBsb3QKCgojICBFdmFsdWF0ZSBjb3JyZWxhdGlvbnMgYmV0d2VlbiBQQ3MgYW5kIG1vZGVsIHZhcmlhYmxlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMrIEFuc3dlciwgIldoYXQgaXMgZHJpdmluZyBiaW9sb2dpY2FsbHkgc2lnbmlmaWNhbnQgdmFyaWFuY2UgaW4gb3VyIGRhdGE/IgpQQ19jb3IgPC0gUENBdG9vbHM6OmVpZ2VuY29ycGxvdCgKICAgIG9ial9wY2EsCiAgICBjb21wb25lbnRzID0gUENBdG9vbHM6OmdldENvbXBvbmVudHMob2JqX3BjYSwgMTo1KSwKICAgIG1ldGF2YXJzID0gYygic3RyYWluIiwgInJlcGxpY2F0ZSIpLAogICAgIyBtZXRhdmFycyA9IGMoInN0cmFpbiIsICJyZXBsaWNhdGUiLCAic2FtcGxlX25hbWUiKSwKICAgIGNvbCA9IGMoIiM3ODVFRjA3NSIsICIjNjQ4RkZGNzUiLCAiI0ZGRkZGRjc1IiwgIiNGRkIwMDA3NSIsICIjRkU2MTAwNzUiKSwKICAgIHNjYWxlID0gRkFMU0UsCiAgICBjb3JGVU4gPSAicGVhcnNvbiIsCiAgICBjb3JNdWx0aXBsZVRlc3RDb3JyZWN0aW9uID0gIkJIIiwKICAgIHBsb3RSc3F1YXJlZCA9IFRSVUUsCiAgICBjb2xGcmFtZSA9ICIjRkZGRkZGIiwKICAgIG1haW4gPSBicXVvdGUoUGVhcnNvbiB+IHJeMiB+IGNvcnJlbGF0ZXMpLAogICAgIyBtYWluID0gIlBDIFBlYXJzb24gci1zcXVhcmVkIGNvcnJlbGF0ZXMiLAogICAgZm9udE1haW4gPSAxLAogICAgdGl0bGVYID0gIlByaW5jaXBhbCBjb21wb25lbnRzIiwKICAgIGZvbnRUaXRsZVggPSAxLAogICAgZm9udExhYlggPSAxLAogICAgdGl0bGVZID0gIk1vZGVsIHZhcmlhYmxlcyIsCiAgICByb3RUaXRsZVkgPSA5MCwKICAgIGZvbnRUaXRsZVkgPSAxLAogICAgZm9udExhYlkgPSAxCikKUENfY29yCgoKIyAgR2V0IGxpc3RzIG9mIHRvcCBsb2FkaW5ncyBmb3IgR08gYW5hbHlzZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIGZvcihpIGluIGMoIlBDMSIsICJQQzIiLCAiUEMzIiwgIlBDNCIpKSB7CmZvcihpIGluIGMoIlBDMSIsICJQQzIiKSkgewogICAgIyBpIDwtICJQQzEiCiAgICAjICBQb3NpdGl2ZQogICAgbG9hZGluZ3NfcG9zX1BDIDwtIHJvd25hbWVzKHRvcF9sb2FkaW5nc19wb3NbW2ldXSlbMTo1MDBdCiAgICBzYXZlX3RpdGxlX3Bvc19QQyA8LSBwYXN0ZTAoCiAgICAgICAgInRvcC01MDAuIiwKICAgICAgICBzdHJpbmdyOjpzdHJfcmVwbGFjZV9hbGwoZ2V0X25hbWVfb2ZfdmFyKGxvYWRpbmdzX3Bvc19QQyksICJfIiwgIi0iKSwKICAgICAgICAiLiIsIGksICIudHh0IgogICAgKQogICAgIyByZWFkcjo6d3JpdGVfdHN2KAogICAgIyAgICAgZHBseXI6OmFzX3RpYmJsZShsb2FkaW5nc19wb3NfUEMpLAogICAgIyAgICAgcGFzdGUwKGFyZ3MkZGlyZWN0b3J5X291dCwgIi8iLCBzYXZlX3RpdGxlX3Bvc19QQyksCiAgICAjICAgICBjb2xfbmFtZXMgPSBGQUxTRQogICAgIyApCiAgICAjVE9ETyBXb3JrIHVwIHNvbWUgbG9naWMgZm9yIGxvY2F0aW9uKHMpIGZvciBvdXRmaWxlcwogICAgCiAgICAjICBOZWdhdGl2ZQogICAgbG9hZGluZ3NfbmVnX1BDIDwtIHJvd25hbWVzKHRvcF9sb2FkaW5nc19uZWdbW2ldXSlbMTo1MDBdCiAgICBzYXZlX3RpdGxlX25lZ19QQyA8LSBwYXN0ZTAoCiAgICAgICAgInRvcC01MDAuIiwKICAgICAgICBzdHJpbmdyOjpzdHJfcmVwbGFjZV9hbGwoZ2V0X25hbWVfb2ZfdmFyKGxvYWRpbmdzX25lZ19QQyksICJfIiwgIi0iKSwKICAgICAgICAiLiIsIGksICIudHh0IgogICAgKQogICAgIyByZWFkcjo6d3JpdGVfdHN2KAogICAgIyAgICAgZHBseXI6OmFzX3RpYmJsZShsb2FkaW5nc19uZWdfUEMpLAogICAgIyAgICAgcGFzdGUwKGFyZ3MkZGlyZWN0b3J5X291dCwgIi8iLCBzYXZlX3RpdGxlX25lZ19QQyksCiAgICAjICAgICBjb2xfbmFtZXMgPSBGQUxTRQogICAgIyApCiAgICAjVE9ETyBXb3JrIHVwIHNvbWUgbG9naWMgZm9yIGxvY2F0aW9uKHMpIGZvciBvdXRmaWxlcwp9CmBgYAo8YnIgLz4KPGJyIC8+CgojIyBJSS4gUnVuIGFuYWx5c2VzIHdpdGggKlMuIGNlcmV2aXNhZSogZmVhdHVyZXMgb25seQojIyMgUGVyZm9ybSBzaXplLWZhY3RvciBlc3RpbWF0aW9uCkhlcmUsIHdlIHN1YnNldCBvdXQgdGhlICpLLiBsYWN0aXMqIGZlYXR1cmVzLiBUaHVzLCB3ZSBhcmUgdXNpbmcgb25seQoqUy4gY2VyZXZpc2lhZSogZmVhdHVyZXMgaW4gdGhlIHNpemUtZmFjdG9yIGVzdGltYXRpb24uIE5vIGNvbnRyb2wgZ2VuZXMgYXJlCnVzZWQuCgpgYGB7ciBJSS4gUGVyZm9ybSBzaXplLWZhY3RvciBlc3RpbWF0aW9uLCBtZXNzYWdlPUZBTFNFfQpkZHNfU0MgPC0gQmlvY0dlbmVyaWNzOjplc3RpbWF0ZVNpemVGYWN0b3JzKAogICAgZGRzW2Rkc0Byb3dSYW5nZXMkZ2Vub21lICE9ICJLX2xhY3RpcyIsIF0KKQpkZHNfU0NAY29sRGF0YQojIG4zLWQgUSBOIHJlcDEgMS40NDQwMjUKIyBuMy1kIFEgTiByZXAyIDEuMTE5NDQ2CiMgbjMtZCBRIE4gcmVwMyAxLjU0NzUwNgojIG8tZCBRIE4gcmVwMSAwLjc3MjY1MwojIG8tZCBRIE4gcmVwMiAwLjUyNjg5NQpgYGAKPGJyIC8+CgojIyMgUnVuIGBERVNlcTJgCiMjIyMgQ2FsbCBgREVTZXEyYCB1c2luZyBkZWZhdWx0IHBhcmFtZXRlcnMKYGBge3IgSUkuIENhbGwgREVTZXEyIHVzaW5nIGRlZmF1bHQgcGFyYW1ldGVycywgZWNobz1UUlVFLCByZXN1bHRzPSdoaWRlJywgbWVzc2FnZT1GQUxTRX0KZGRzX1NDIDwtIERFU2VxMjo6REVTZXEoZGRzX1NDKQoKIyAgQ2hlY2sgbW9kZWwgaW5mb3JtYXRpb24KREVTZXEyOjpyZXN1bHRzTmFtZXMoZGRzX1NDKVsyXQojICBbMV0gInN0cmFpbl9vLmRfdnNfbjMuZCIgICNIRVJFCiMrIFRodXMsIHRoZSBtb2RlbCB2YXJpZXMgb24gc3RyYWluLCBPc1RJUi1kZXBsZXRpb24gaXMgdGhlIG51bWVyYXRvciwKIysgTmFiMy1kZXBsZXRpb24gaXMgdGhlIGRlbm9taW5hdG9yCiMrICAgICAtIE51bWVyYXRvcjogInRvcCIgaW4gTUEgcGxvdHMsICJyaWdodCIgaW4gdm9sY2FubyBwbG90cwojKyAgICAgLSBEZW5vbWluYXRvcjogImJvdHRvbSIgaW4gTUEgcGxvdHMsICJsZWZ0IiBpbiB2b2xjYW5vIHBsb3RzCmBgYAo8YnIgLz4KCiMjIyMgQ2FsbCBgREVTZXEyOjpyZXN1bHRzKClgCmBgYHtyIElJLiBDYWxsIERFU2VxMjo6cmVzdWx0cygpLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQojICBTZXQgdXAgbmVjZXNzYXJ5IHBhcmFtZXRlcnMgZm9yIGdlbmVyYXRpb24gb2YgREVTZXEyIHJlc3VsdHMgdGFibGUKaW5kZXBlbmRlbnRfZmlsdGVyaW5nIDwtIFRSVUUKdGhyZXNob2xkX3AgPC0gMC4wNQp0aHJlc2hvbGRfbGZjIDwtIDAKCiMgIE91dHB1dCBhIERFU2VxMiBEYXRhRnJhbWUgb2JqZWN0CkRHRV91bnNocnVua2VuX0RGX1NDIDwtIERFU2VxMjo6cmVzdWx0cygKICAgIGRkc19TQywKICAgIG5hbWUgPSBERVNlcTI6OnJlc3VsdHNOYW1lcyhkZHNfU0MpWzJdLAogICAgaW5kZXBlbmRlbnRGaWx0ZXJpbmcgPSBpbmRlcGVuZGVudF9maWx0ZXJpbmcsCiAgICBhbHBoYSA9IHRocmVzaG9sZF9wLAogICAgbGZjVGhyZXNob2xkID0gdGhyZXNob2xkX2xmYywKICAgIGZvcm1hdCA9ICJEYXRhRnJhbWUiCikKCiMgIE91dHB1dCBhIEdSYW5nZXMgb2JqZWN0LCB3aGljaCB3ZSBjYW4gZWFzaWx5IGFkZCB0byBhbmQgY29udmVydCB0byBvdGhlcgojKyBmb3JtYXRzIChzdWNoIGFzIGEgdGliYmxlKQpER0VfdW5zaHJ1bmtlbl9HUl9TQyA8LSBERVNlcTI6OnJlc3VsdHMoCiAgICBkZHNfU0MsCiAgICBuYW1lID0gREVTZXEyOjpyZXN1bHRzTmFtZXMoZGRzX1NDKVsyXSwKICAgIGluZGVwZW5kZW50RmlsdGVyaW5nID0gaW5kZXBlbmRlbnRfZmlsdGVyaW5nLAogICAgYWxwaGEgPSB0aHJlc2hvbGRfcCwKICAgIGxmY1RocmVzaG9sZCA9IHRocmVzaG9sZF9sZmMsCiAgICBmb3JtYXQgPSAiR1JhbmdlcyIKKQpER0VfdW5zaHJ1bmtlbl9HUl9TQyRmZWF0dXJlIDwtIE1hdHJpeEdlbmVyaWNzOjpyb3dSYW5nZXMoZGRzX1NDKSRmZWF0dXJlCkRHRV91bnNocnVua2VuX0dSX1NDJHR5cGUgPC0gTWF0cml4R2VuZXJpY3M6OnJvd1JhbmdlcyhkZHNfU0MpJHR5cGUKREdFX3Vuc2hydW5rZW5fR1JfU0MkZ2Vub21lIDwtIE1hdHJpeEdlbmVyaWNzOjpyb3dSYW5nZXMoZGRzX1NDKSRnZW5vbWUKCnRfREdFX1NDIDwtIERHRV91bnNocnVua2VuX0dSX1NDICU+JQogICAgZHBseXI6OmFzX3RpYmJsZSgpICU+JQogICAgZHBseXI6OnJlbmFtZShjaHIgPSBzZXFuYW1lcykKCnJtKGluZGVwZW5kZW50X2ZpbHRlcmluZywgdGhyZXNob2xkX3AsIHRocmVzaG9sZF9sZmMpCmBgYAo8YnIgLz4KCiMjIyMgTWFrZSBhbiBNQSBwbG90IHRoYXQgY29sb3JzIGZlYXR1cmVzIGJ5IGluZGVwZW5kZW50IGZpbHRlcmluZwpgYGB7ciBJSS4gTWFrZSBhbiBNQSBwbG90OiBCLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQojICBTZXQgdXAgdGVtcG9yYXJ5IHZhcmlhYmxlICd0YmwnLCB3aGljaCB3aWxsIGJlIHBhc3NlZCB0byBnZ3Bsb3QKdGJsIDwtIHRfREdFX1NDCnRibCA8LSB0Ymxbd2l0aCh0YmwsIG9yZGVyKGxvZzJGb2xkQ2hhbmdlKSksIF0KdGJsJHRocmVzaG9sZCA8LSBhcy5mYWN0b3IodGJsJHBhZGogPD0gMC4wNSkKdGJsJGxvZzEwYmFzZU1lYW4gPC0gaWZlbHNlKAogICAgaXMuaW5maW5pdGUobG9nMTAodGJsJGJhc2VNZWFuKSksIE5BLCBsb2cxMCh0YmwkYmFzZU1lYW4pCikKCnRpdGxlIDwtIHBhc3RlMCgKICAgICJNQSBwbG90IHwgUy4gY2VyZXZpc2lhZSBmZWF0dXJlcyB8XG4iLAogICAgInNpemUgZmFjdG9ycyBlc3RpbWF0ZWQgd2l0aCBhbGwgUy4gY2VyZXZpc2lhZSBmZWF0dXJlcyIKKQpzdWJ0aXRsZSA8LSBwYXN0ZSgKICAgICJwb2ludHM6IFMuIGNlcmV2aXNpYWUgZmVhdHVyZXMiLAogICAgInwgdG9wOiB1cCBpbiBOYWIzIGRlcGxldGlvbiIsCiAgICAifCBib3R0b206IHVwIGluIE9zVElSIGRlcGxldGlvbiIKKSAgIyBbMV0gInN0cmFpbl9vLmRfdnNfbjMuZCIKZ2dwbG90KHRibCwgYWVzKHggPSBsb2cxMGJhc2VNZWFuLCB5ID0gbG9nMkZvbGRDaGFuZ2UsIGNvbG91ciA9IHRocmVzaG9sZCkpICsKICAgIGdlb21fcG9pbnQoYWxwaGEgPSAwLjI1LCBzaXplID0gMC41KSArCiAgICAjIGdlb21faGxpbmUoYWVzKHlpbnRlcmNlcHQgPSAwKSwgY29sb3VyID0gIiMwMDAwMDAiLCBsaW5ld2lkdGggPSAwLjI1KSArCiAgICBnZW9tX2hsaW5lKGFlcyh5aW50ZXJjZXB0ID0gMCksIGNvbG91ciA9ICIjMDAwMDAwIiwgc2l6ZSA9IDAuMjUpICsKICAgICMgeWxpbShjKG1pbih0YmwkbG9nMkZvbGRDaGFuZ2UpLCBtYXgodGJsJGxvZzJGb2xkQ2hhbmdlKSkpICsKICAgIHlsaW0oYygtMTQsIDE0KSkgKwogICAgeGxhYigibG9nMTAobWVhbiBub3JtYWxpemVkIGNvdW50cykiKSArCiAgICB5bGFiKCJsb2cyKGZvbGQgY2hhbmdlKSIpICsKICAgIHNjYWxlX2NvbG91cl9kaXNjcmV0ZShuYW1lID0gInEg4omkIDAuMDUiKSArCiAgICBnZ3RpdGxlKHRpdGxlLCBzdWJ0aXRsZSkgKwogICAgdGhlbWVfc2xpY2sKI1RPRE8gMS8yIEV4cGxhaW4gYW5kIG1ha2UgYSBkZWNpc2lvbiByZWdhcmRpbmcgdXNlIG9mICdzaXplJyBvciAnbGluZXdpZHRoJwojVE9ETyAyLzIgcGFyYW1ldGVycwoKI05PVEUgMS80IE5vdGUgdGhhdCB0aGUgZGF0YSBhcmUgbm90IGNlbnRlcmVkIG9uIGxvZzIoZm9sZCBjaGFuZ2UpID0gMDsKI05PVEUgMi80IGluc3RlYWQsIHRoZXkgc2VlbSB0byBzbG9wZSBkb3dud2FyZCB3aXRoIGEgZ2VudGxlIGdyYWRpZW50OyB0aGlzCiNOT1RFIDMvNCBzdWdnZXN0cyB0aGF0IGNlbnRlcmluZyB0aGUgZGF0YSB3aXRoIGFsbCBTLiBjZXJldmlzaWFlIGZlYXR1cmVzIGlzCiNOT1RFIDQvNCBub3QgYW4gZWZmZWN0aXZlIHJlYWQtZGVwdGggbm9ybWFsaXphdGlvbgoKIyAgQ3JlYXRlIGEgdmVjdG9yIG9mIGZlYXR1cmVzIHRoYXQgYm90aCBwYXNzZWQgaW5kZXBlbmRlbnQgZmlsdGVyaW5nIChhbmQgdGh1cwojKyBoYXZlIGFuIGluaGVyZW50bHkgaGlnaCBtZWFuIGV4cHJlc3Npb24pIGFuZCBhcmUgbm90IHN0YXRpc3RpY2FsbHkKIysgc2lnbmlmaWNhbnQ7IHRoaXMgdmVjdG9yIHNpZ25pZmllcyBmZWF0dXJlcyB0aGF0IGFyZSAic3RhYmx5IGV4cHJlc3NlZCIKIysgYmV0d2VlbiBjb25kaXRpb25zCnRibCRzdGFibHlfZXhwcmVzc2VkIDwtIGlmZWxzZSgKICAgICFpcy5uYSh0YmwkdGhyZXNob2xkKSAmIHRibCRwYWRqID4gMC4wNSwKICAgIFRSVUUsCiAgICBGQUxTRQopCnN0YWJseV9leHByZXNzZWRfU0MgPC0gdGJsJGZlYXR1cmVbdGJsJHN0YWJseV9leHByZXNzZWQgPT0gVFJVRV0KCnJtKHRibCwgdGl0bGUsIHN1YnRpdGxlKQpgYGAKPGJyIC8+CgojIyMjIE1ha2UgYSB2b2xjYW5vIHBsb3QKYGBge3IgSUkuIE1ha2UgYSB2b2xjYW5vIHBsb3QsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CiMgIElkZW50aWZ5IGFuZCBpc29sYXRlIHRoZSB0b3AgNSB1cHJlZ3VsYXRlZCBmZWF0dXJlcyBhbmQgdGhlIHRvcCA1IGRvd24tCiMrIHJlZ3VsYXRlZCBmZWF0dXJlcwphbGwgPC0gdF9ER0VfU0MkZmVhdHVyZQpzZWxlY3Rpb25fZG93biA8LSB0X0RHRV9TQyAlPiUKICAgIGRwbHlyOjpmaWx0ZXIobG9nMkZvbGRDaGFuZ2UgPCAwKSAlPiUKICAgIGRwbHlyOjphcnJhbmdlKHBhZGopICU+JQogICAgZHBseXI6OnNsaWNlKDE6NSkKc2VsZWN0aW9uX3VwIDwtIHRfREdFX1NDICU+JQogICAgZHBseXI6OmZpbHRlcihsb2cyRm9sZENoYW5nZSA+IDApICU+JQogICAgZHBseXI6OmFycmFuZ2UocGFkaikgJT4lCiAgICBkcGx5cjo6c2xpY2UoMTo1KQpzZWxlY3Rpb24gPC0gYyhzZWxlY3Rpb25fZG93bltbImZlYXR1cmUiXV0sIHNlbGVjdGlvbl91cFtbImZlYXR1cmUiXV0pICU+JQogICAgICAgIGFzLmNoYXJhY3RlcigpCgp0aXRsZSA8LSBwYXN0ZTAoCiAgICAidm9sY2FubyBwbG90IHwgUy4gY2VyZXZpc2lhZSBmZWF0dXJlcyB8XG4iLAogICAgInNpemUgZmFjdG9ycyBlc3RpbWF0ZWQgd2l0aCBhbGwgUy4gY2VyZXZpc2lhZSBmZWF0dXJlcyIKKQpzdWJ0aXRsZSA8LSBwYXN0ZSgKICAgICJwb2ludHM6IFMuIGNlcmV2aXNpYWUgZmVhdHVyZXMiLAogICAgInwgbGVmdDogdXAgaW4gT3NUSVIgZGVwbGV0aW9uIiwKICAgICJ8IHJpZ2h0OiB1cCBpbiBOYWIzIGRlcGxldGlvbiIsCiAgICAifFxubGFiZWxzOiB0b3AgNSBPc1RJUiBkZXAuIGFuZCB0b3AgNSBOYWIzIGRlcC4gZmVhdHVyZXMiCikgICMgWzFdICJzdHJhaW5fby5kX3ZzX24zLmQiCnBfU0MgPC0gcGxvdF92b2xjYW5vKAogICAgdGFibGUgPSB0X0RHRV9TQywKICAgIGxhYmVsID0gYWxsLAogICAgc2VsZWN0aW9uID0gc2VsZWN0aW9uLAogICAgbGFiZWxfc2l6ZSA9IDIuNSwKICAgIHBfY3V0b2ZmID0gMC4wNSwKICAgIEZDX2N1dG9mZiA9IDEsCiAgICB4bGltID0gYygtMTQsIDE0KSwKICAgIHlsaW0gPSBjKDAsIDMxMCksCiAgICBjb2xvciA9ICIjNTJCRTlCIiwKICAgIHRpdGxlID0gdGl0bGUsCiAgICBzdWJ0aXRsZSA9IHN1YnRpdGxlCikKcF9TQwojIHNhdmVfdm9sY2FubygKIyAgICAgZmlsZSA9ICJ0ZXN0LnBkZiIsCiMgICAgIHBsb3QgPSBwLAojICAgICB3aWR0aCA9IDIsCiMgICAgIGhlaWdodCA9IDMKIyApCgpybShhbGwsIHNlbGVjdGlvbiwgc2VsZWN0aW9uX3VwLCBzZWxlY3Rpb25fZG93biwgdGl0bGUsIHN1YnRpdGxlKQojVE9ETyAxLzIgV2h5IGFyZSB0aGVyZSAxMiBsYWJlbHMgaW4gdGhlIHBsb3QsIHR3byBvZiB3aGljaCBhcmUgbm90IHRvcAojVE9ETyBhbnl0aGluZz8gQmFzZWQgb24gdGhlIGFib3ZlIGNvZGUsIFRoZXJlIHNob3VsZCBvbmx5IGJlIDEwLiAjRklYTUUKYGBgCjxiciAvPgo8YnIgLz4KCiMjIElJSS4gUnVuIGFuYWx5c2VzIHdpdGggKksuIGxhY3RpcyogZmVhdHVyZXMgb25seQojIyMgUGVyZm9ybSBzaXplLWZhY3RvciBlc3RpbWF0aW9uCkhlcmUsIHdlIHN1YnNldCBvdXQmbWRhc2g7aS5lLiwgcmVtb3ZlJm1kYXNoO3RoZSAqUy4gY2VyZXZpc2lhZSogZmVhdHVyZXMgYW5kCmFyZSB0aHVzIG9ubHkgYW5hbHl6aW5nICpLLiBsYWN0aXMqIGZlYXR1cmVzLCB1c2luZyBhbGwgKksuIGxhY3RpcyogZmVhdHVyZXMKaW4gdGhlIHNpemUtZmFjdG9yIGVzdGltYXRpb24uCgpgYGB7ciBJSUkuIFBlcmZvcm0gc2l6ZS1mYWN0b3IgZXN0aW1hdGlvbiwgZWNobz1UUlVFLCByZXN1bHRzPSdoaWRlJywgbWVzc2FnZT1GQUxTRX0KZGRzX0tMIDwtIEJpb2NHZW5lcmljczo6ZXN0aW1hdGVTaXplRmFjdG9ycygKICAgIGRkc1tkZHNAcm93UmFuZ2VzJGdlbm9tZSAhPSAiU19jZXJldmlzaWFlIiwgXQopCmRkc19LTEBjb2xEYXRhCiMgbjMtZCBRIE4gcmVwMSAwLjkwNzM3MwojIG4zLWQgUSBOIHJlcDIgMS4wMzQ5MTMKIyBuMy1kIFEgTiByZXAzIDAuOTQ0NjE4CiMgby1kIFEgTiByZXAxIDEuMDAxMTI2CiMgby1kIFEgTiByZXAyIDEuMTMwOTkyCmBgYAo8YnIgLz4KCiMjIyBSdW4gYERFU2VxMmAKIyMjIyBDYWxsIGBERVNlcTJgIHVzaW5nIGRlZmF1bHQgcGFyYW1ldGVycwpgYGB7ciBJSUkuIENhbGwgREVTZXEyIHVzaW5nIGRlZmF1bHQgcGFyYW1ldGVycywgZWNobz1UUlVFLCByZXN1bHRzPSdoaWRlJywgbWVzc2FnZT1GQUxTRX0KZGRzX0tMIDwtIERFU2VxMjo6REVTZXEoZGRzX0tMKQoKIyAgQ2hlY2sgbW9kZWwgaW5mb3JtYXRpb24KREVTZXEyOjpyZXN1bHRzTmFtZXMoZGRzX0tMKVsyXQojICBbMV0gInN0cmFpbl9vLmRfdnNfbjMuZCIgICNIRVJFCiMrIFRodXMsIHRoZSBtb2RlbCB2YXJpZXMgb24gc3RyYWluLCBPc1RJUi1kZXBsZXRpb24gaXMgdGhlIG51bWVyYXRvciwKIysgTmFiMy1kZXBsZXRpb24gaXMgdGhlIGRlbm9taW5hdG9yCiMrICAgICAtIE51bWVyYXRvcjogInRvcCIgaW4gTUEgcGxvdHMsICJyaWdodCIgaW4gdm9sY2FubyBwbG90cwojKyAgICAgLSBEZW5vbWluYXRvcjogImJvdHRvbSIgaW4gTUEgcGxvdHMsICJsZWZ0IiBpbiB2b2xjYW5vIHBsb3RzCmBgYAo8YnIgLz4KCiMjIyMgQ2FsbCBgREVTZXEyOjpyZXN1bHRzKClgCmBgYHtyIElJSS4gQ2FsbCBERVNlcTI6OnJlc3VsdHMoKSwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KIyAgU2V0IHVwIG5lY2Vzc2FyeSBwYXJhbWV0ZXJzIGZvciBnZW5lcmF0aW9uIG9mIERFU2VxMiByZXN1bHRzIHRhYmxlCmluZGVwZW5kZW50X2ZpbHRlcmluZyA8LSBUUlVFCnRocmVzaG9sZF9wIDwtIDAuMDUKdGhyZXNob2xkX2xmYyA8LSAwCgojICBPdXRwdXQgYSBERVNlcTIgRGF0YUZyYW1lIG9iamVjdApER0VfdW5zaHJ1bmtlbl9ERl9LTCA8LSBERVNlcTI6OnJlc3VsdHMoCiAgICBkZHNfS0wsCiAgICBuYW1lID0gREVTZXEyOjpyZXN1bHRzTmFtZXMoZGRzX0tMKVsyXSwKICAgIGluZGVwZW5kZW50RmlsdGVyaW5nID0gaW5kZXBlbmRlbnRfZmlsdGVyaW5nLAogICAgYWxwaGEgPSB0aHJlc2hvbGRfcCwKICAgIGxmY1RocmVzaG9sZCA9IHRocmVzaG9sZF9sZmMsCiAgICBmb3JtYXQgPSAiRGF0YUZyYW1lIgopCgojICBPdXRwdXQgYSBHUmFuZ2VzIG9iamVjdCwgd2hpY2ggd2UgY2FuIGVhc2lseSBhZGQgdG8gYW5kIGNvbnZlcnQgdG8gb3RoZXIKIysgZm9ybWF0cyAoc3VjaCBhcyBhIHRpYmJsZSkKREdFX3Vuc2hydW5rZW5fR1JfS0wgPC0gREVTZXEyOjpyZXN1bHRzKAogICAgZGRzX0tMLAogICAgbmFtZSA9IERFU2VxMjo6cmVzdWx0c05hbWVzKGRkc19LTClbMl0sCiAgICBpbmRlcGVuZGVudEZpbHRlcmluZyA9IGluZGVwZW5kZW50X2ZpbHRlcmluZywKICAgIGFscGhhID0gdGhyZXNob2xkX3AsCiAgICBsZmNUaHJlc2hvbGQgPSB0aHJlc2hvbGRfbGZjLAogICAgZm9ybWF0ID0gIkdSYW5nZXMiCikKREdFX3Vuc2hydW5rZW5fR1JfS0wkZmVhdHVyZSA8LSBNYXRyaXhHZW5lcmljczo6cm93UmFuZ2VzKGRkc19LTCkkZmVhdHVyZQpER0VfdW5zaHJ1bmtlbl9HUl9LTCR0eXBlIDwtIE1hdHJpeEdlbmVyaWNzOjpyb3dSYW5nZXMoZGRzX0tMKSR0eXBlCkRHRV91bnNocnVua2VuX0dSX0tMJGdlbm9tZSA8LSBNYXRyaXhHZW5lcmljczo6cm93UmFuZ2VzKGRkc19LTCkkZ2Vub21lCgp0X0RHRV9LTCA8LSBER0VfdW5zaHJ1bmtlbl9HUl9LTCAlPiUKICAgIGRwbHlyOjphc190aWJibGUoKSAlPiUKICAgIGRwbHlyOjpyZW5hbWUoY2hyID0gc2VxbmFtZXMpCgpybShpbmRlcGVuZGVudF9maWx0ZXJpbmcsIHRocmVzaG9sZF9wLCB0aHJlc2hvbGRfbGZjKQpgYGAKPGJyIC8+CgojIyMjIE1ha2UgYW4gTUEgcGxvdCB0aGF0IGNvbG9ycyBmZWF0dXJlcyBieSBpbmRlcGVuZGVudCBmaWx0ZXJpbmcKYGBge3IgSUlJLiBNYWtlIGFuIE1BIHBsb3Q6IEIsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CiMgIFNldCB1cCB0ZW1wb3JhcnkgdmFyaWFibGUgJ3RibCcsIHdoaWNoIHdpbGwgYmUgcGFzc2VkIHRvIGdncGxvdAp0YmwgPC0gdF9ER0VfS0wKdGJsIDwtIHRibFt3aXRoKHRibCwgb3JkZXIobG9nMkZvbGRDaGFuZ2UpKSwgXQp0YmwkdGhyZXNob2xkIDwtIGFzLmZhY3Rvcih0YmwkcGFkaiA8PSAwLjA1KQp0YmwkbG9nMTBiYXNlTWVhbiA8LSBpZmVsc2UoCiAgICBpcy5pbmZpbml0ZShsb2cxMCh0YmwkYmFzZU1lYW4pKSwgTkEsIGxvZzEwKHRibCRiYXNlTWVhbikKKQojSEVSRQp0aXRsZSA8LSBwYXN0ZTAoCiAgICAiTUEgcGxvdCB8IEsuIGxhY3RpcyBmZWF0dXJlcyB8XG4iLAogICAgInNpemUgZmFjdG9ycyBlc3RpbWF0ZWQgd2l0aCBhbGwgSy4gbGFjdGlzIGZlYXR1cmVzIgopCnN1YnRpdGxlIDwtIHBhc3RlKAogICAgInBvaW50czogSy4gbGFjdGlzIGZlYXR1cmVzIiwKICAgICJ8IHRvcDogdXAgaW4gTmFiMyBkZXBsZXRpb24iLAogICAgInwgYm90dG9tOiB1cCBpbiBPc1RJUiBkZXBsZXRpb24iCikgICMgWzFdICJzdHJhaW5fby5kX3ZzX24zLmQiCmdncGxvdCh0YmwsIGFlcyh4ID0gbG9nMTBiYXNlTWVhbiwgeSA9IGxvZzJGb2xkQ2hhbmdlLCBjb2xvdXIgPSB0aHJlc2hvbGQpKSArCiAgICBnZW9tX3BvaW50KGFscGhhID0gMC4yNSwgc2l6ZSA9IDAuNSkgKwogICAgIyBnZW9tX2hsaW5lKGFlcyh5aW50ZXJjZXB0ID0gMCksIGNvbG91ciA9ICIjMDAwMDAwIiwgbGluZXdpZHRoID0gMC4yNSkgKwogICAgZ2VvbV9obGluZShhZXMoeWludGVyY2VwdCA9IDApLCBjb2xvdXIgPSAiIzAwMDAwMCIsIHNpemUgPSAwLjI1KSArCiAgICAjIHlsaW0oYyhtaW4odGJsJGxvZzJGb2xkQ2hhbmdlKSwgbWF4KHRibCRsb2cyRm9sZENoYW5nZSkpKSArCiAgICB5bGltKGMoLTE0LCAxNCkpICsKICAgIHhsYWIoImxvZzEwKG1lYW4gbm9ybWFsaXplZCBjb3VudHMpIikgKwogICAgeWxhYigibG9nMihmb2xkIGNoYW5nZSkiKSArCiAgICBzY2FsZV9jb2xvdXJfZGlzY3JldGUobmFtZSA9ICJxIOKJpCAwLjA1IikgKwogICAgZ2d0aXRsZSh0aXRsZSwgc3VidGl0bGUpICsKICAgIHRoZW1lX3NsaWNrCiNUT0RPIDEvMiBFeHBsYWluIGFuZCBtYWtlIGEgZGVjaXNpb24gcmVnYXJkaW5nIHVzZSBvZiAnc2l6ZScgb3IgJ2xpbmV3aWR0aCcKI1RPRE8gMi8yIHBhcmFtZXRlcnMKCiMgIENyZWF0ZSBhIHZlY3RvciBvZiBmZWF0dXJlcyB0aGF0IGJvdGggcGFzc2VkIGluZGVwZW5kZW50IGZpbHRlcmluZyBhbmQgYXJlCiMrIG5vdCBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50OyB3ZSBjYW4gc2F5IHRoYXQgdGhpcyB2ZWN0b3Igc2lnbmlmaWVzCiMrIGZlYXR1cmVzIHRoYXQgYXJlICJzdGFibHkgZXhwcmVzc2VkIiBiZXR3ZWVuIGNvbmRpdGlvbnMKdGJsJHN0YWJseV9leHByZXNzZWQgPC0gaWZlbHNlKAogICAgIWlzLm5hKHRibCR0aHJlc2hvbGQpICYgdGJsJHBhZGogPiAwLjA1LAogICAgVFJVRSwKICAgIEZBTFNFCikKc3RhYmx5X2V4cHJlc3NlZF9LTCA8LSB0YmwkZmVhdHVyZVt0Ymwkc3RhYmx5X2V4cHJlc3NlZCA9PSBUUlVFXQojTk9URSBQcm9iYWJseSBuZWVkIHRvIGJlIG1vcmUgc3RyaW5nZW50IGhlcmUKCnJtKHRibCwgdGl0bGUsIHN1YnRpdGxlKQpgYGAKPGJyIC8+CgojIyMjIE1ha2UgYSB2b2xjYW5vIHBsb3QKYGBge3IgSUlJLiBNYWtlIGEgdm9sY2FubyBwbG90LCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQphbGwgPC0gdF9ER0VfS0wkZmVhdHVyZQojIHNlbGVjdGlvbl9kb3duIDwtIHRfREdFX0tMICU+JQojICAgICBkcGx5cjo6ZmlsdGVyKGxvZzJGb2xkQ2hhbmdlIDwgMCkgJT4lCiMgICAgIGRwbHlyOjphcnJhbmdlKHBhZGopICU+JQojICAgICBkcGx5cjo6c2xpY2UoMTo1KQojIHNlbGVjdGlvbl91cCA8LSB0X0RHRV9LTCAlPiUKIyAgICAgZHBseXI6OmZpbHRlcihsb2cyRm9sZENoYW5nZSA+IDApICU+JQojICAgICBkcGx5cjo6YXJyYW5nZShwYWRqKSAlPiUKIyAgICAgZHBseXI6OnNsaWNlKDE6NSkKIyBzZWxlY3Rpb24gPC0gYyhzZWxlY3Rpb25fZG93bltbImZlYXR1cmUiXV0sIHNlbGVjdGlvbl91cFtbImZlYXR1cmUiXV0pICU+JQojICAgICAgICAgYXMuY2hhcmFjdGVyKCkgICNOT1RFIE5vdGhpbmcgc2lnbmlmaWNhbnQsIHNvIG5vIGxhYmVsaW5nIG5lZWRlZAoKIyAgSW5pdGlhbGl6ZSBhbiBlbXB0eSAnc2VsZWN0aW9uJyB2ZWN0b3IgYi9jIHRoZSBmdW5jdGlvbiByZXF1aXJlcyBzb21lIGxhYmVscwpzZWxlY3Rpb24gPC0gYyhyZXAoIiIsIDEwKSkKCnRpdGxlIDwtIHBhc3RlMCgKICAgICJ2b2xjYW5vIHBsb3QgfCBLLiBsYWN0aXMgZmVhdHVyZXMgfFxuIiwKICAgICJzaXplIGZhY3RvcnMgZXN0aW1hdGVkIHdpdGggYWxsIEsuIGxhY3RpcyBmZWF0dXJlcyIKKQpzdWJ0aXRsZSA8LSBwYXN0ZSgKICAgICJwb2ludHM6IEsuIGxhY3RpcyBmZWF0dXJlcyIsCiAgICAifCBsZWZ0OiB1cCBpbiBPc1RJUiBkZXBsZXRpb24iLAogICAgInwgcmlnaHQ6IHVwIGluIE5hYjMgZGVwbGV0aW9uIiwKICAgICJ8XG5sYWJlbHM6IHRvcCA1IE9zVElSIGRlcC4gYW5kIHRvcCA1IE5hYjMgZGVwLiBmZWF0dXJlcyIKKSAgIyBbMV0gInN0cmFpbl9vLmRfdnNfbjMuZCIKcF9LTCA8LSBwbG90X3ZvbGNhbm8oCiAgICB0YWJsZSA9IHRfREdFX0tMLAogICAgbGFiZWwgPSBhbGwsCiAgICBzZWxlY3Rpb24gPSBzZWxlY3Rpb24sCiAgICBsYWJlbF9zaXplID0gMi41LAogICAgcF9jdXRvZmYgPSAwLjA1LAogICAgRkNfY3V0b2ZmID0gMSwKICAgIHhsaW0gPSBjKC0xNCwgMTQpLAogICAgeWxpbSA9IGMoMCwgMzEwKSwKICAgIGNvbG9yID0gIiM0NDhFRTIiLAogICAgdGl0bGUgPSB0aXRsZSwKICAgIHN1YnRpdGxlID0gc3VidGl0bGUKKQpwX0tMCiMgc2F2ZV92b2xjYW5vKAojICAgICBmaWxlID0gInRlc3QucGRmIiwKIyAgICAgcGxvdCA9IHAsCiMgICAgIHdpZHRoID0gMiwKIyAgICAgaGVpZ2h0ID0gMwojICkKCiMgcm0oYWxsLCBzZWxlY3Rpb24sIHNlbGVjdGlvbl91cCwgc2VsZWN0aW9uX2Rvd24sIHRpdGxlLCBzdWJ0aXRsZSkKcm0oYWxsLCBzZWxlY3Rpb24sIHRpdGxlLCBzdWJ0aXRsZSkKYGBgCjxiciAvPgo8YnIgLz4KCiMjIElWLiBSdW4gYW5hbHlzZXMgb2YgKlMuQy4qIGluIHdoaWNoIGFsbCAqSy5MLiogYXJlIGBjb250cm9sR2VuZXNgCiMjIyBQZXJmb3JtIHNpemUtZmFjdG9yIGVzdGltYXRpb24KVG8gcnVuIGFuYWx5c2VzIHVzaW5nIGFsbCAqSy5sYWN0aXMqIGZlYXR1cmVzIGFzIGBjb250cm9sR2VuZXNgLCB3ZSB1c2UgYQpsb2dpY2FsIHZlY3RvciAoYSB2ZWN0b3IgY29tcG9zZWQgb2YgZWxlbWVudHMgd2l0aCB2YWx1ZXMgb2YgZWl0aGVyIGBUUlVFYCBvcgpgRkFMU0VgKSBvYnRhaW5lZCBmcm9tIHBhcnNpbmcgdGhlIGByb3dSYW5nZXNgIGRhdGFmcmFtZSB3aXRoaW4gdGhlIGBkZHNgCm9iamVjdC4gSW4gZXNzZW5jZSwgd2UncmUgc2F5aW5nLCAiUmV0dXJuIGBUUlVFYCBpZiB0aGUgYHJvd1Jhbmdlc2AgdmFyaWFibGUKYGdlbm9tZWAgaGFzIGEgdmFsdWUgb2YgYEtfbGFjdGlzYDsgb3RoZXJ3aXNlLCByZXR1cm4gYEZBTFNFYC4iIFRoZW4sCmBCaW9jR2VuZXJpY3M6OmVzdGltYXRlU2l6ZUZhY3RvcnMoKWAgaXMgdXNpbmcgdGhlIHZhbHVlcyBhc3NvY2lhdGVkIHdpdGggdGhvc2UKYFRSVUVgcyB0byBpc29sYXRlIHRoZSBjb3VudHMgZm9yICpLLiBsYWN0aXMqLXNwZWNpZmljIGZlYXR1cmVzLCBpbiB0dXJuCnVzaW5nIHRob3NlIHZhbHVlcyB0byBjYWxjdWxhdGUgc2l6ZSBmYWN0b3JzLgoKYGBge3IgSVYuIFBlcmZvcm0gc2l6ZS1mYWN0b3IgZXN0aW1hdGlvbiwgZWNobz1UUlVFLCByZXN1bHRzPSdoaWRlJywgbWVzc2FnZT1GQUxTRX0KIyAgUmVjYWxjdWxhdGUgc2l6ZSBmYWN0b3JzIHVzaW5nIEsuIGxhY3RpcyBmZWF0dXJlcyBhcyBgY29udHJvbEdlbmVzYApkZHNfU0MuY3RybF9LTCA8LSBCaW9jR2VuZXJpY3M6OmVzdGltYXRlU2l6ZUZhY3RvcnMoCiAgICBkZHMsCiAgICBjb250cm9sR2VuZXMgPSAoZGRzQHJvd1JhbmdlcyRnZW5vbWUgPT0gIktfbGFjdGlzIikKKQpkZHNfU0MuY3RybF9LTEBjb2xEYXRhCiMgIFVzaW5nIGFsbCBvZiB0aGUgSy4gbGFjdGlzIGZlYXR1cmVzIGFzIGBjb250cm9sR2VuZXNgCiMgbjMtZCBRIE4gcmVwMSAwLjkwNzM3MwojIG4zLWQgUSBOIHJlcDIgMS4wMzQ5MTMKIyBuMy1kIFEgTiByZXAzIDAuOTQ0NjE4CiMgby1kIFEgTiByZXAxIDEuMDAxMTI2CiMgby1kIFEgTiByZXAyIDEuMTMwOTkyCmBgYAo8YnIgLz4KCiMjIyBSdW4gYERFU2VxMmAKIyMjIyBDYWxsIGBERVNlcTJgIHVzaW5nIGRlZmF1bHQgcGFyYW1ldGVycwpTaW5jZSB3ZSd2ZSBhbHJlYWR5IGNhbGN1bGF0ZWQgdGhlIHNpemUgZmFjdG9ycywgSSB0aGluayB3ZSBjYW4gZXhjbHVkZQoqSy4gbGFjdGlzKiBmZWF0dXJlcyBmcm9tIG91ciB3b3JrIGZyb20gaGVyZSBvbiBvdXQuIFdlIGhhdmUgdG8gZG8gc29tZSBpbmRleApzdWJzZXR0aW5nIHRvIGFjY29tcGxpc2ggdGhpcyAoc2VlIGJlbG93KS4KYGBge3IgSVYuIENhbGwgREVTZXEyIHVzaW5nIGRlZmF1bHQgcGFyYW1ldGVycywgZWNobz1UUlVFLCByZXN1bHRzPSdoaWRlJywgbWVzc2FnZT1GQUxTRX0KZGRzX1NDLmN0cmxfS0wgPC0gREVTZXEyOjpERVNlcSgKICAgIGRkc19TQy5jdHJsX0tMW2Rkc19TQy5jdHJsX0tMQHJvd1JhbmdlcyRnZW5vbWUgIT0gIktfbGFjdGlzIiwgXQopCgojICBDaGVjayBtb2RlbCBpbmZvcm1hdGlvbgpERVNlcTI6OnJlc3VsdHNOYW1lcyhkZHNfU0MuY3RybF9LTClbMl0KIyAgWzFdICJzdHJhaW5fby5kX3ZzX24zLmQiICAjSEVSRQojKyBUaHVzLCB0aGUgbW9kZWwgdmFyaWVzIG9uIHN0cmFpbiwgT3NUSVItZGVwbGV0aW9uIGlzIHRoZSBudW1lcmF0b3IsCiMrIE5hYjMtZGVwbGV0aW9uIGlzIHRoZSBkZW5vbWluYXRvcgojKyAgICAgLSBOdW1lcmF0b3I6ICJ0b3AiIGluIE1BIHBsb3RzLCAicmlnaHQiIGluIHZvbGNhbm8gcGxvdHMKIysgICAgIC0gRGVub21pbmF0b3I6ICJib3R0b20iIGluIE1BIHBsb3RzLCAibGVmdCIgaW4gdm9sY2FubyBwbG90cwpgYGAKPGJyIC8+CgojIyMjIENhbGwgYERFU2VxMjo6cmVzdWx0cygpYApgYGB7ciBJVi4gQ2FsbCBERVNlcTI6OnJlc3VsdHMoKSwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KIyAgU2V0IHVwIG5lY2Vzc2FyeSBwYXJhbWV0ZXJzIGZvciBnZW5lcmF0aW9uIG9mIERFU2VxMiByZXN1bHRzIHRhYmxlCmluZGVwZW5kZW50X2ZpbHRlcmluZyA8LSBUUlVFCnRocmVzaG9sZF9wIDwtIDAuMDUKdGhyZXNob2xkX2xmYyA8LSAwCgojICBPdXRwdXQgYSBERVNlcTIgRGF0YUZyYW1lIG9iamVjdApER0VfdW5zaHJ1bmtlbl9ERl9TQy5jdHJsX0tMIDwtIERFU2VxMjo6cmVzdWx0cygKICAgIGRkc19TQy5jdHJsX0tMLAogICAgbmFtZSA9IERFU2VxMjo6cmVzdWx0c05hbWVzKGRkc19TQy5jdHJsX0tMKVsyXSwKICAgIGluZGVwZW5kZW50RmlsdGVyaW5nID0gaW5kZXBlbmRlbnRfZmlsdGVyaW5nLAogICAgYWxwaGEgPSB0aHJlc2hvbGRfcCwKICAgIGxmY1RocmVzaG9sZCA9IHRocmVzaG9sZF9sZmMsCiAgICBmb3JtYXQgPSAiRGF0YUZyYW1lIgopCgojICBPdXRwdXQgYSBHUmFuZ2VzIG9iamVjdCwgd2hpY2ggd2UgY2FuIGVhc2lseSBhZGQgdG8gYW5kIGNvbnZlcnQgdG8gb3RoZXIKIysgZm9ybWF0cyAoc3VjaCBhcyBhIHRpYmJsZSkKREdFX3Vuc2hydW5rZW5fR1JfU0MuY3RybF9LTCA8LSBERVNlcTI6OnJlc3VsdHMoCiAgICBkZHNfU0MuY3RybF9LTCwKICAgIG5hbWUgPSBERVNlcTI6OnJlc3VsdHNOYW1lcyhkZHNfU0MuY3RybF9LTClbMl0sCiAgICBpbmRlcGVuZGVudEZpbHRlcmluZyA9IGluZGVwZW5kZW50X2ZpbHRlcmluZywKICAgIGFscGhhID0gdGhyZXNob2xkX3AsCiAgICBsZmNUaHJlc2hvbGQgPSB0aHJlc2hvbGRfbGZjLAogICAgZm9ybWF0ID0gIkdSYW5nZXMiCikKREdFX3Vuc2hydW5rZW5fR1JfU0MuY3RybF9LTCRmZWF0dXJlIDwtCiAgICBNYXRyaXhHZW5lcmljczo6cm93UmFuZ2VzKGRkc19TQy5jdHJsX0tMKSRmZWF0dXJlCkRHRV91bnNocnVua2VuX0dSX1NDLmN0cmxfS0wkdHlwZSA8LQogICAgTWF0cml4R2VuZXJpY3M6OnJvd1JhbmdlcyhkZHNfU0MuY3RybF9LTCkkdHlwZQpER0VfdW5zaHJ1bmtlbl9HUl9TQy5jdHJsX0tMJGdlbm9tZSA8LQogICAgTWF0cml4R2VuZXJpY3M6OnJvd1JhbmdlcyhkZHNfU0MuY3RybF9LTCkkZ2Vub21lCgp0X0RHRV9TQy5jdHJsX0tMIDwtIERHRV91bnNocnVua2VuX0dSX1NDLmN0cmxfS0wgJT4lIGRwbHlyOjphc190aWJibGUoKQoKcm0oaW5kZXBlbmRlbnRfZmlsdGVyaW5nLCB0aHJlc2hvbGRfcCwgdGhyZXNob2xkX2xmYykKYGBgCjxiciAvPgoKIyMjIyBNYWtlIGFuIE1BIHBsb3QgdGhhdCBjb2xvcnMgZmVhdHVyZXMgYnkgaW5kZXBlbmRlbnQgZmlsdGVyaW5nCmBgYHtyIElWLiBNYWtlIGFuIE1BIHBsb3Q6IEIsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CiMgIFNldCB1cCB0ZW1wb3JhcnkgdmFyaWFibGUgJ3RibCcsIHdoaWNoIHdpbGwgYmUgcGFzc2VkIHRvIGdncGxvdAp0YmwgPC0gdF9ER0VfU0MuY3RybF9LTAp0YmwgPC0gdGJsW3dpdGgodGJsLCBvcmRlcihsb2cyRm9sZENoYW5nZSkpLCBdCnRibCR0aHJlc2hvbGQgPC0gYXMuZmFjdG9yKHRibCRwYWRqIDw9IDAuMDUpCnRibCRsb2cxMGJhc2VNZWFuIDwtIGlmZWxzZSgKICAgIGlzLmluZmluaXRlKGxvZzEwKHRibCRiYXNlTWVhbikpLCBOQSwgbG9nMTAodGJsJGJhc2VNZWFuKQopCgp0aXRsZSA8LSBwYXN0ZTAoCiAgICAiTUEgcGxvdCB8IFMuIGNlcmV2aXNpYWUgZmVhdHVyZXMgfFxuIiwKICAgICJzaXplIGZhY3RvcnMgZXN0aW1hdGVkIHdpdGggYWxsIEsuIGxhY3RpcyBmZWF0dXJlcyIKKQpzdWJ0aXRsZSA8LSBwYXN0ZSgKICAgICJwb2ludHM6IFMuIGNlcmV2aXNpYWUgZmVhdHVyZXMiLAogICAgInwgdG9wOiB1cCBpbiBOYWIzIGRlcGxldGlvbiIsCiAgICAifCBib3R0b206IHVwIGluIE9zVElSIGRlcGxldGlvbiIKKSAgIyBbMV0gInN0cmFpbl9vLmRfdnNfbjMuZCIKZ2dwbG90KHRibCwgYWVzKHggPSBsb2cxMGJhc2VNZWFuLCB5ID0gbG9nMkZvbGRDaGFuZ2UsIGNvbG91ciA9IHRocmVzaG9sZCkpICsKICAgIGdlb21fcG9pbnQoYWxwaGEgPSAwLjI1LCBzaXplID0gMC41KSArCiAgICAjIGdlb21faGxpbmUoYWVzKHlpbnRlcmNlcHQgPSAwKSwgY29sb3VyID0gIiMwMDAwMDAiLCBsaW5ld2lkdGggPSAwLjI1KSArCiAgICBnZW9tX2hsaW5lKGFlcyh5aW50ZXJjZXB0ID0gMCksIGNvbG91ciA9ICIjMDAwMDAwIiwgc2l6ZSA9IDAuMjUpICsKICAgICMgeWxpbShjKG1pbih0YmwkbG9nMkZvbGRDaGFuZ2UpLCBtYXgodGJsJGxvZzJGb2xkQ2hhbmdlKSkpICsKICAgIHlsaW0oYygtMTQsIDE0KSkgKwogICAgeGxhYigibG9nMTAobWVhbiBub3JtYWxpemVkIGNvdW50cykiKSArCiAgICB5bGFiKCJsb2cyKGZvbGQgY2hhbmdlKSIpICsKICAgIHNjYWxlX2NvbG91cl9kaXNjcmV0ZShuYW1lID0gInEg4omkIDAuMDUiKSArCiAgICBnZ3RpdGxlKHRpdGxlLCBzdWJ0aXRsZSkgKwogICAgdGhlbWVfc2xpY2sKI1RPRE8gMS8yIEV4cGxhaW4gYW5kIG1ha2UgYSBkZWNpc2lvbiByZWdhcmRpbmcgdXNlIG9mICdzaXplJyBvciAnbGluZXdpZHRoJwojVE9ETyAyLzIgcGFyYW1ldGVycwoKI05PVEUgMS8yIFRoZSB1c2Ugb2YgSy4gbGFjdGlzIGZlYXR1cmVzIGZvciBzaXplLWZhY3RvciBlc3RpbWF0aW9uIGNlbnRlcnMgdGhlCiNOT1RFIDIvMiBkYXRhIHZlcnkgbmljZWx5IQoKIyAgQ3JlYXRlIGEgdmVjdG9yIG9mIGZlYXR1cmVzIHRoYXQgYm90aCBwYXNzZWQgaW5kZXBlbmRlbnQgZmlsdGVyaW5nIChhbmQgdGh1cwojKyBoYXZlIGFuIGluaGVyZW50bHkgaGlnaCBtZWFuIGV4cHJlc3Npb24pIGFuZCBhcmUgbm90IHN0YXRpc3RpY2FsbHkKIysgc2lnbmlmaWNhbnQ7IHRoaXMgdmVjdG9yIHNpZ25pZmllcyBmZWF0dXJlcyB0aGF0IGFyZSAic3RhYmx5IGV4cHJlc3NlZCIKIysgYmV0d2VlbiBjb25kaXRpb25zCnRibCRzdGFibHlfZXhwcmVzc2VkIDwtIGlmZWxzZSgKICAgICFpcy5uYSh0YmwkdGhyZXNob2xkKSAmIHRibCRwYWRqID4gMC4wNSwKICAgIFRSVUUsCiAgICBGQUxTRQopCnN0YWJseV9leHByZXNzZWRfU0MuY3RybF9LTCA8LSB0Ymwkc3RhYmx5X2V4cHJlc3NlZFsKICAgICFpcy5uYSh0Ymwkc3RhYmx5X2V4cHJlc3NlZCkKXQoKcm0odGJsLCB0aXRsZSwgc3VidGl0bGUpCmBgYAoKIyMjIyBNYWtlIGEgdm9sY2FubyBwbG90CmBgYHtyIElWLiBNYWtlIGEgdm9sY2FubyBwbG90LCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQphbGwgPC0gdF9ER0VfU0MuY3RybF9LTCRmZWF0dXJlCnNlbGVjdGlvbl9kb3duIDwtIHRfREdFX1NDLmN0cmxfS0wgJT4lCiAgICBkcGx5cjo6ZmlsdGVyKGxvZzJGb2xkQ2hhbmdlIDwgMCkgJT4lCiAgICBkcGx5cjo6YXJyYW5nZShwYWRqKSAlPiUKICAgIGRwbHlyOjpzbGljZSgxOjUpCnNlbGVjdGlvbl91cCA8LSB0X0RHRV9TQy5jdHJsX0tMICU+JQogICAgZHBseXI6OmZpbHRlcihsb2cyRm9sZENoYW5nZSA+IDApICU+JQogICAgZHBseXI6OmFycmFuZ2UocGFkaikgJT4lCiAgICBkcGx5cjo6c2xpY2UoMTo1KQpzZWxlY3Rpb24gPC0gYyhzZWxlY3Rpb25fZG93bltbImZlYXR1cmUiXV0sIHNlbGVjdGlvbl91cFtbImZlYXR1cmUiXV0pICU+JQogICAgICAgIGFzLmNoYXJhY3RlcigpCgp0aXRsZSA8LSBwYXN0ZTAoCiAgICAidm9sY2FubyBwbG90IHwgUy4gY2VyZXZpc2lhZSBmZWF0dXJlcyB8XG4iLAogICAgInNpemUgZmFjdG9ycyBlc3RpbWF0ZWQgd2l0aCBhbGwgSy4gbGFjdGlzIGZlYXR1cmVzIgopCnN1YnRpdGxlIDwtIHBhc3RlKAogICAgInBvaW50czogUy4gY2VyZXZpc2lhZSBmZWF0dXJlcyIsCiAgICAifCBsZWZ0OiB1cCBpbiBPc1RJUiBkZXBsZXRpb24iLAogICAgInwgcmlnaHQ6IHVwIGluIE5hYjMgZGVwbGV0aW9uIiwKICAgICJ8XG5sYWJlbHM6IHRvcCA1IE9zVElSIGRlcC4gYW5kIHRvcCA1IE5hYjMgZGVwLiBmZWF0dXJlcyIKKSAgIyBbMV0gInN0cmFpbl9vLmRfdnNfbjMuZCIKcF9TQy5jdHJsX0tMLjEgPC0gcGxvdF92b2xjYW5vKAogICAgdGFibGUgPSB0X0RHRV9TQy5jdHJsX0tMLAogICAgbGFiZWwgPSBhbGwsCiAgICBzZWxlY3Rpb24gPSBzZWxlY3Rpb24sCiAgICBsYWJlbF9zaXplID0gMi41LAogICAgcF9jdXRvZmYgPSAwLjA1LAogICAgRkNfY3V0b2ZmID0gMSwKICAgIHhsaW0gPSBjKC0xNCwgMTQpLAogICAgeWxpbSA9IGMoMCwgMzEwKSwKICAgIGNvbG9yID0gIiNBMDIwRjAiLAogICAgdGl0bGUgPSB0aXRsZSwKICAgIHN1YnRpdGxlID0gc3VidGl0bGUKKQpwX1NDLmN0cmxfS0wuMQoKcF9TQy5jdHJsX0tMLjIgPC0gcGxvdF92b2xjYW5vKAogICAgdGFibGUgPSB0X0RHRV9TQy5jdHJsX0tMLAogICAgbGFiZWwgPSBhbGwsCiAgICBzZWxlY3Rpb24gPSBzZWxlY3Rpb24sCiAgICBsYWJlbF9zaXplID0gMi41LAogICAgcF9jdXRvZmYgPSAwLjA1LAogICAgRkNfY3V0b2ZmID0gMSwKICAgIHhsaW0gPSBjKC0xMSwgMTEpLAogICAgeWxpbSA9IGMoMCwgMTIwKSwKICAgIGNvbG9yID0gIiNBMDIwRjAiLAogICAgdGl0bGUgPSB0aXRsZSwKICAgIHN1YnRpdGxlID0gc3VidGl0bGUKKQpwX1NDLmN0cmxfS0wuMgojIHNhdmVfdm9sY2FubygKIyAgICAgZmlsZSA9ICJ0ZXN0LnBkZiIsCiMgICAgIHBsb3QgPSBwLAojICAgICB3aWR0aCA9IDIsCiMgICAgIGhlaWdodCA9IDMKIyApCgpybShhbGwsIHNlbGVjdGlvbiwgc2VsZWN0aW9uX3VwLCBzZWxlY3Rpb25fZG93biwgdGl0bGUsIHN1YnRpdGxlKQpgYGAKPGJyIC8+Cg==